home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / dix / window.c < prev   
Encoding:
C/C++ Source or Header  |  1991-02-28  |  108.1 KB  |  4,326 lines

  1. /***********************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /* $XConsortium: window.c,v 5.50 90/02/28 16:09:42 keith Exp $ */
  26.  
  27. #include "X.h"
  28. #define NEED_REPLIES
  29. #define NEED_EVENTS
  30. #include "Xproto.h"
  31. #include "misc.h"
  32. #include "scrnintstr.h"
  33. #include "os.h"
  34. #include "regionstr.h"
  35. #include "validate.h"
  36. #include "windowstr.h"
  37. #include "input.h"
  38. #include "resource.h"
  39. #include "colormapst.h"
  40. #include "cursorstr.h"
  41. #include "dixstruct.h"
  42. #include "gcstruct.h"
  43. #include "servermd.h"
  44.  
  45. /******
  46.  * Window stuff for server 
  47.  *
  48.  *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
  49.  *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
  50.  *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
  51.  *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
  52.  *
  53.  ******/
  54.  
  55. static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
  56. static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
  57.  
  58. typedef struct _ScreenSaverStuff {
  59.     WindowPtr pWindow;
  60.     XID       wid;
  61.     BYTE      blanked;
  62. } ScreenSaverStuffRec;
  63.  
  64. #define SCREEN_IS_BLANKED   0
  65. #define SCREEN_ISNT_SAVED   1
  66. #define SCREEN_IS_TILED     2
  67. #define SCREEN_IS_BLACK        3
  68.  
  69. #define HasSaverWindow(v)   ((v) == SCREEN_IS_TILED || (v) == SCREEN_IS_BLACK)
  70.  
  71. extern int ScreenSaverBlanking, ScreenSaverAllowExposures;
  72. int screenIsSaved = SCREEN_SAVER_OFF;
  73.  
  74. static ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
  75.  
  76. extern WindowPtr *WindowTable;
  77. extern void (* ReplySwapVector[256]) ();
  78.  
  79. static void ResizeChildrenWinSize();
  80. extern void CheckCursorConfinement();
  81. extern void DeleteWindowFromAnySelections();
  82. extern void DeleteWindowFromAnyEvents();
  83. extern Mask EventMaskForClient();
  84. extern void WindowHasNewCursor();
  85. extern void RecalculateDeliverableEvents();
  86. extern long random();
  87. static Bool MarkOverlappedWindows();
  88. static void SetWinSize(), SetBorderSize();
  89. static Bool TileScreenSaver();
  90.  
  91. #define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
  92.                   CWDontPropagate | CWOverrideRedirect | CWCursor )
  93.  
  94. #define BOXES_OVERLAP(b1, b2) \
  95.       (!( ((b1)->x2 <= (b2)->x1)  || \
  96.         ( ((b1)->x1 >= (b2)->x2)) || \
  97.         ( ((b1)->y2 <= (b2)->y1)) || \
  98.         ( ((b1)->y1 >= (b2)->y2)) ) )
  99.  
  100. #define RedirectSend(pWin) \
  101.     ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
  102.  
  103. #define SubSend(pWin) \
  104.     ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
  105.  
  106. #define StrSend(pWin) \
  107.     ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
  108.  
  109. #define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
  110.  
  111. /*
  112.  * For SaveUnders using backing-store. The idea is that when a window is mapped
  113.  * with saveUnder set TRUE, any windows it obscures will have its backing
  114.  * store turned on setting the DIXsaveUnder bit,
  115.  * The backing-store code must be written to allow for this
  116.  */
  117.  
  118. /*
  119.  * this is the configuration parameter "NO_BACK_SAVE"
  120.  * it means that any existant backing store should not 
  121.  * be used to implement save unders.
  122.  */
  123.  
  124. #ifndef NO_BACK_SAVE
  125.  
  126. #define DO_SAVE_UNDERS(pWin)    ((pWin)->drawable.pScreen->saveUnderSupport ==\
  127.                  USE_DIX_SAVE_UNDERS)
  128.  
  129. /*
  130.  * saveUnderSupport is set to this magic value when using DIXsaveUnders
  131.  */
  132.  
  133. #define USE_DIX_SAVE_UNDERS    0x40
  134.  
  135. static int numSaveUndersViewable = 0;
  136. static int deltaSaveUndersViewable = 0;
  137.  
  138. /*-
  139.  *-----------------------------------------------------------------------
  140.  * CheckSubSaveUnder --
  141.  *    Check all the inferiors of a window for coverage by saveUnder
  142.  *    windows. Called from ChangeSaveUnder and CheckSaveUnder.
  143.  *
  144.  * Results:
  145.  *    TRUE if any windows need to have backing-store removed.
  146.  *
  147.  * Side Effects:
  148.  *    Windows may have backing-store turned on or off.
  149.  *
  150.  *-----------------------------------------------------------------------
  151.  */
  152. Bool
  153. CheckSubSaveUnder(pParent, pFirst, pRegion)
  154.     register WindowPtr     pParent;        /* Parent to check */
  155.     WindowPtr        pFirst;        /* first reconfigured window */
  156.     RegionPtr          pRegion;        /* Initial area obscured by saveUnder */
  157. {
  158.     register WindowPtr    pChild;            /* Current child */
  159.     register ScreenPtr     pScreen;        /* Screen to use */
  160.     RegionRec          SubRegion;     /* Area of children obscured */
  161.     Bool        res = FALSE;
  162.  
  163.     pScreen = pParent->drawable.pScreen;
  164.     if (pChild = pParent->firstChild)
  165.     {
  166.     /*
  167.      * build region above first changed window
  168.      */
  169.  
  170.     for (; pChild != pFirst; pChild = pChild->nextSib)
  171.         if (pChild->viewable && pChild->saveUnder)
  172.         (* pScreen->Union) (pRegion, pRegion, &pChild->borderSize);
  173.     
  174.     (*pScreen->RegionInit)(&SubRegion, NullBox, 0);
  175.  
  176.     /*
  177.      * check region below and including first changed window
  178.      */
  179.  
  180.     for (; pChild; pChild = pChild->nextSib)
  181.     {
  182.         if (pChild->viewable)
  183.         {
  184.         /*
  185.          * don't save under nephew/niece windows;
  186.          * use a separate region
  187.          */
  188.  
  189.         if (pChild->firstChild)
  190.         {
  191.             (* pScreen->RegionCopy) (&SubRegion, pRegion);
  192.             res |= CheckSubSaveUnder(pChild, pChild->firstChild,
  193.                          &SubRegion);
  194.         }
  195.         else
  196.             res |= CheckSubSaveUnder(pChild, pChild->firstChild,
  197.                          pRegion);
  198.  
  199.         if (pChild->saveUnder)
  200.             (* pScreen->Union) (pRegion, pRegion, &pChild->borderSize);
  201.         }
  202.     }
  203.  
  204.      (* pScreen->RegionUninit) (&SubRegion);
  205.     }
  206.  
  207.     /*
  208.      * Never, ever, turn on backing store for save-unders
  209.      * on the root window
  210.      */
  211.  
  212.     if (!pParent->parent)
  213.     return res;
  214.  
  215.     switch ((*pScreen->RectIn) (pRegion,
  216.                 (*pScreen->RegionExtents)(&pParent->borderSize)))
  217.     {
  218.     case rgnOUT:
  219.     pParent->DIXsaveUnder = FALSE;
  220.     res = TRUE;
  221.     break;
  222.     default:
  223.     if (!(pParent->DIXsaveUnder))
  224.     {
  225.         pParent->DIXsaveUnder = TRUE;
  226.         (* pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
  227.     }
  228.     break;
  229.     }
  230.     return res;
  231. }
  232.  
  233. /*-
  234.  *-----------------------------------------------------------------------
  235.  * CheckSaveUnder --
  236.  *    See if a window's backing-store state should be changed because
  237.  *    it is or is not obscured by a sibling or child window with saveUnder.
  238.  *
  239.  * Results:
  240.  *    TRUE if any windows need to have backing-store removed.
  241.  *
  242.  * Side Effects:
  243.  *    If the window's state should be changed, it is.
  244.  *
  245.  *-----------------------------------------------------------------------
  246.  */
  247. Bool
  248. CheckSaveUnder (pWin)
  249.     register WindowPtr pWin;       /* Window to check */
  250. {
  251.     RegionRec    rgn;        /* Extent of siblings with saveUnder */
  252.     Bool    res;
  253.  
  254.     numSaveUndersViewable += deltaSaveUndersViewable;
  255.     if (!deltaSaveUndersViewable && !numSaveUndersViewable)
  256.     return FALSE;
  257.     deltaSaveUndersViewable = 0;
  258.     (* pWin->drawable.pScreen->RegionInit) (&rgn, NullBox, 1);
  259.     res = CheckSubSaveUnder (pWin->parent, pWin->nextSib, &rgn);
  260.     (*pWin->drawable.pScreen->RegionUninit) (&rgn);
  261.     return res;
  262. }
  263.  
  264.  
  265. /*-
  266.  *-----------------------------------------------------------------------
  267.  * ChangeSaveUnder --
  268.  *    Change the save-under state of a tree of windows. Called when
  269.  *    a window with saveUnder TRUE is mapped/unmapped/reconfigured.
  270.  *    
  271.  * Results:
  272.  *    TRUE if any windows need to have backing-store removed.
  273.  *
  274.  * Side Effects:
  275.  *    Windows may have backing-store turned on or off.
  276.  *
  277.  *-----------------------------------------------------------------------
  278.  */
  279. Bool
  280. ChangeSaveUnder(pWin, first)
  281.     register WindowPtr     pWin;
  282.     WindowPtr            first;             /* First window to check.
  283.                      * Used when pWin was restacked */
  284. {
  285.     RegionRec    rgn;      /* Area obscured by saveUnder windows */
  286.     register ScreenPtr pScreen;
  287.     Bool    res;
  288.  
  289.     numSaveUndersViewable += deltaSaveUndersViewable;
  290.     if (!deltaSaveUndersViewable && !numSaveUndersViewable)
  291.     return FALSE;
  292.     deltaSaveUndersViewable = 0;
  293.     pScreen = pWin->drawable.pScreen;
  294.     (* pScreen->RegionInit) (&rgn, NullBox, 1);
  295.     res = CheckSubSaveUnder (pWin->parent, first, &rgn);
  296.     (* pScreen->RegionUninit) (&rgn);
  297.     return res;
  298. }
  299.  
  300. /*-
  301.  *-----------------------------------------------------------------------
  302.  * DoChangeSaveUnder --
  303.  *    Actually turn backing-store off for those windows that no longer
  304.  *    need to have it on.
  305.  *
  306.  * Results:
  307.  *    None.
  308.  *
  309.  * Side Effects:
  310.  *    Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
  311.  *    windows affected.
  312.  *
  313.  *-----------------------------------------------------------------------
  314.  */
  315. void
  316. DoChangeSaveUnder(pWin, pFirst)
  317.     WindowPtr          pWin;
  318.     WindowPtr        pFirst;
  319. {
  320.     register WindowPtr pChild;
  321.     Bool (* ChangeWindowAttributes)();
  322.  
  323.     ChangeWindowAttributes = pWin->drawable.pScreen->ChangeWindowAttributes;
  324.     if (!pWin->DIXsaveUnder &&
  325.     (pWin->backingStore == NotUseful) && pWin->backStorage)
  326.     (*ChangeWindowAttributes)(pWin, CWBackingStore);
  327.     if (!(pChild = pFirst))
  328.     return;
  329.     while (1)
  330.     {
  331.     if (!pChild->DIXsaveUnder &&
  332.         (pChild->backingStore == NotUseful) && pChild->backStorage)
  333.         (*ChangeWindowAttributes)(pChild, CWBackingStore);
  334.     if (pChild->firstChild)
  335.     {
  336.         pChild = pChild->firstChild;
  337.         continue;
  338.     }
  339.     while (!pChild->nextSib)
  340.     {
  341.         pChild = pChild->parent;
  342.         if (pChild == pWin)
  343.         return;
  344.     }
  345.     pChild = pChild->nextSib;
  346.     }
  347. }
  348. #endif /* DO_SAVE_UNDER */
  349.  
  350. #ifdef DEBUG
  351. /******
  352.  * PrintWindowTree
  353.  *    For debugging only
  354.  ******/
  355.  
  356. int
  357. PrintChildren(p1, indent)
  358.     WindowPtr p1;
  359.     int indent;
  360. {
  361.     WindowPtr p2;
  362.     int i;
  363.  
  364.     while (p1)
  365.     {
  366.         p2 = p1->firstChild;
  367.         for (i=0; i<indent; i++) ErrorF( " ");
  368.     ErrorF( "%x\n", p1->drawable.id);
  369.         miPrintRegion(&p1->clipList);
  370.     PrintChildren(p2, indent+4);
  371.     p1 = p1->nextSib;
  372.     }
  373. }
  374.  
  375. PrintWindowTree()
  376. {
  377.     int i;
  378.     WindowPtr pWin, p1;
  379.  
  380.     for (i=0; i<screenInfo.numScreens; i++)
  381.     {
  382.     ErrorF( "WINDOW %d\n", i);
  383.     pWin = WindowTable[i];
  384.         miPrintRegion(&pWin->clipList);
  385.     p1 = pWin->firstChild;
  386.     PrintChildren(p1, 4);
  387.     }
  388. }
  389. #endif
  390.  
  391. /*
  392.  * allocate an entry in the per-window private data structures
  393.  */
  394.  
  395. static int  windowPrivateCount;
  396.  
  397. void
  398. ResetWindowPrivates()
  399. {
  400.     windowPrivateCount = 0;
  401. }
  402.  
  403. int
  404. AllocateWindowPrivateIndex()
  405. {
  406.     return windowPrivateCount++;
  407. }
  408.  
  409. int
  410. TraverseTree(pWin, func, data)
  411.     register WindowPtr pWin;
  412.     int (*func)();
  413.     pointer data;
  414. {
  415.     register int result;
  416.     register WindowPtr pChild;
  417.  
  418.     if (!(pChild = pWin))
  419.        return(WT_NOMATCH);
  420.     while (1)
  421.     {
  422.     result = (* func)(pChild, data);
  423.     if (result == WT_STOPWALKING)
  424.         return(WT_STOPWALKING);
  425.     if ((result == WT_WALKCHILDREN) && pChild->firstChild)
  426.     {
  427.         pChild = pChild->firstChild;
  428.         continue;
  429.     }
  430.     while (!pChild->nextSib && (pChild != pWin))
  431.         pChild = pChild->parent;
  432.     if (pChild == pWin)
  433.         break;
  434.     pChild = pChild->nextSib;
  435.     }
  436.     return(WT_NOMATCH);
  437. }
  438.  
  439. /*****
  440.  * WalkTree
  441.  *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
  442.  *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
  443.  *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
  444.  *   exit WalkTree.  Does depth-first traverse.
  445.  *****/
  446.  
  447. int
  448. WalkTree(pScreen, func, data)
  449.     ScreenPtr pScreen;
  450.     int (* func)();
  451.     pointer data;
  452. {
  453.     return(TraverseTree(WindowTable[pScreen->myNum], func, data));
  454. }
  455.  
  456. /*****
  457.  *  HandleExposures(pWin)
  458.  *    starting at pWin, draw background in any windows that have exposure
  459.  *    regions, translate the regions, restore any backing store,
  460.  *    and then send any regions stille xposed to the client
  461.  *****/
  462.  
  463. static void
  464. HandleExposures(pWin)
  465.     WindowPtr pWin;
  466. {
  467.     register WindowPtr pChild;
  468.     register ValidatePtr val;
  469.     Bool (* RegionNotEmpty)();
  470.     void (* RegionUninit)();
  471.     void (* WindowExposures)();
  472.  
  473.     pChild = pWin;
  474.     RegionNotEmpty = pChild->drawable.pScreen->RegionNotEmpty;
  475.     RegionUninit = pChild->drawable.pScreen->RegionUninit;
  476.     WindowExposures = pChild->drawable.pScreen->WindowExposures;
  477.     while (1)
  478.     {
  479.     if (val = pChild->valdata)
  480.     {
  481.         if ((*RegionNotEmpty)(&val->after.borderExposed))
  482.         (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
  483.                             &val->after.borderExposed,
  484.                             PW_BORDER);
  485.         (*RegionUninit)(&val->after.borderExposed);
  486.         (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
  487.         (*RegionUninit)(&val->after.exposed);
  488.         xfree(val);
  489.         pChild->valdata = (ValidatePtr)NULL;
  490.         if (pChild->firstChild)
  491.         {
  492.         pChild = pChild->firstChild;
  493.         continue;
  494.         }
  495.     }
  496.     while (!pChild->nextSib && (pChild != pWin))
  497.         pChild = pChild->parent;
  498.     if (pChild == pWin)
  499.         break;
  500.     pChild = pChild->nextSib;
  501.     }
  502. }
  503.  
  504. /* hack for forcing backing store on all windows */
  505. int    defaultBackingStore = NotUseful;
  506. /* hack to force no backing store */
  507. Bool    disableBackingStore = FALSE;
  508. /* hack to force no save unders */
  509. Bool    disableSaveUnders = FALSE;
  510.  
  511. static void
  512. SetWindowToDefaults(pWin)
  513.     register WindowPtr pWin;
  514. {
  515.     pWin->prevSib = NullWindow;
  516.     pWin->firstChild = NullWindow;
  517.     pWin->lastChild = NullWindow;
  518.  
  519.     pWin->valdata = (ValidatePtr)NULL;
  520.     pWin->optional = (WindowOptPtr)NULL;
  521.     pWin->cursorIsNone = TRUE;
  522.  
  523.     pWin->backingStore = NotUseful;
  524.     pWin->DIXsaveUnder = FALSE;
  525.     pWin->backStorage = (pointer) NULL;
  526.  
  527.     pWin->mapped = FALSE;           /* off */
  528.     pWin->realized = FALSE;     /* off */
  529.     pWin->viewable = FALSE;
  530.     pWin->visibility = VisibilityNotViewable;
  531.     pWin->overrideRedirect = FALSE;
  532.     pWin->saveUnder = FALSE;
  533.  
  534.     pWin->bitGravity = ForgetGravity;
  535.     pWin->winGravity = NorthWestGravity;
  536.  
  537.     pWin->eventMask = 0;
  538.     pWin->deliverableEvents = 0;
  539.     pWin->dontPropagate = 0;
  540. }
  541.  
  542. static void
  543. MakeRootTile(pWin)
  544.     WindowPtr pWin;
  545. {
  546.     ScreenPtr pScreen = pWin->drawable.pScreen;
  547.     GCPtr pGC;
  548.     unsigned char back[128];
  549.     int len = PixmapBytePad(4, 1);
  550.     register unsigned char *from, *to;
  551.     register int i, j;
  552.  
  553.     pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
  554.                             pScreen->rootDepth);
  555.  
  556.     pWin->backgroundState = BackgroundPixmap;
  557.     pGC = GetScratchGC(pScreen->rootDepth, pScreen);
  558.     if (!pWin->background.pixmap || !pGC)
  559.     FatalError("cound not create root tile");
  560.  
  561.     {
  562.     CARD32 attributes[2];
  563.  
  564.     attributes[0] = pScreen->whitePixel;
  565.     attributes[1] = pScreen->blackPixel;
  566.  
  567.     (void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
  568.     }
  569.  
  570.    ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
  571.  
  572.    from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
  573.    to = back;
  574.  
  575.    for (i = 4; i > 0; i--, from++)
  576.     for (j = len; j > 0; j--)
  577.         *to++ = *from;
  578.  
  579.    (*pGC->ops->PutImage)(pWin->background.pixmap, pGC, 1,
  580.                 0, 0, 4, 4, 0, XYBitmap, back);
  581.  
  582.    FreeScratchGC(pGC);
  583.  
  584. }
  585.  
  586. static WindowPtr
  587. AllocateWindow(pScreen)
  588.     ScreenPtr pScreen;
  589. {
  590.     WindowPtr pWin;
  591.     register char *ptr;
  592.     register DevUnion *ppriv;
  593.     register unsigned *sizes;
  594.     register unsigned size;
  595.     register int i;
  596.  
  597.     pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
  598.     if (pWin)
  599.     {
  600.     ppriv = (DevUnion *)(pWin + 1);
  601.     pWin->devPrivates = ppriv;
  602.     sizes = pScreen->WindowPrivateSizes;
  603.     ptr = (char *)(ppriv + windowPrivateCount);
  604.     for (i = windowPrivateCount; --i >= 0; ppriv++, sizes++)
  605.     {
  606.         if (size = *sizes)
  607.         {
  608.         ppriv->ptr = (pointer)ptr;
  609.         ptr += size;
  610.         }
  611.         else
  612.         ppriv->ptr = (pointer)NULL;
  613.     }
  614.     }
  615.     return pWin;
  616. }
  617.  
  618. /*****
  619.  * CreateRootWindow
  620.  *    Makes a window at initialization time for specified screen
  621.  *****/
  622.  
  623. Bool
  624. CreateRootWindow(pScreen)
  625.     ScreenPtr    pScreen;
  626. {
  627.     WindowPtr    pWin;
  628.     BoxRec    box;
  629.     PixmapFormatRec *format;
  630.  
  631.     pWin = AllocateWindow(pScreen);
  632.     if (!pWin)
  633.     return FALSE;
  634.  
  635.     savedScreenInfo[pScreen->myNum].pWindow = NULL;
  636.     savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
  637.     screenIsSaved = SCREEN_SAVER_OFF;
  638.  
  639.     WindowTable[pScreen->myNum] = pWin;
  640.  
  641.     pWin->drawable.pScreen = pScreen;
  642.     pWin->drawable.type = DRAWABLE_WINDOW;
  643.  
  644.     pWin->drawable.depth = pScreen->rootDepth;
  645.     for (format = screenInfo.formats;
  646.      format->depth != pScreen->rootDepth;
  647.      format++)
  648.     ;
  649.     pWin->drawable.bitsPerPixel = format->bitsPerPixel;
  650.  
  651.     pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  652.  
  653.     pWin->parent = NullWindow;
  654.     SetWindowToDefaults(pWin);
  655.  
  656.     pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
  657.  
  658.     pWin->optional->dontPropagateMask = 0;
  659.     pWin->optional->otherEventMasks = 0;
  660.     pWin->optional->otherClients = NULL;
  661.     pWin->optional->passiveGrabs = NULL;
  662.     pWin->optional->userProps = NULL;
  663.     pWin->optional->backingBitPlanes = ~0L;
  664.     pWin->optional->backingPixel = 0;
  665. #ifdef SHAPE
  666.     pWin->optional->boundingShape = NULL;
  667.     pWin->optional->clipShape = NULL;
  668. #endif
  669. #ifdef XINPUT
  670.     pWin->optional->inputMasks = NULL;
  671. #endif
  672.     pWin->optional->colormap = pScreen->defColormap;
  673.     pWin->optional->visual = pScreen->rootVisual;
  674.  
  675.     pWin->nextSib = NullWindow;
  676.  
  677.     pWin->drawable.id = FakeClientID(0);
  678.  
  679.     pWin->origin.x = pWin->origin.y = 0;
  680.     pWin->drawable.height = pScreen->height;
  681.     pWin->drawable.width = pScreen->width;
  682.     pWin->drawable.x = pWin->drawable.y = 0;
  683.  
  684.     box.x1 = 0;
  685.     box.y1 = 0;
  686.     box.x2 = pScreen->width;
  687.     box.y2 = pScreen->height;
  688.     (* pScreen->RegionInit)(&pWin->clipList, &box, 1);
  689.     (* pScreen->RegionInit)(&pWin->winSize, &box, 1);
  690.     (* pScreen->RegionInit)(&pWin->borderSize, &box, 1);
  691.     (* pScreen->RegionInit)(&pWin->borderClip, &box, 1);
  692.  
  693.     pWin->drawable.class = InputOutput;
  694.     pWin->optional->visual = pScreen->rootVisual;
  695.  
  696.     pWin->backgroundState = BackgroundPixel;
  697.     pWin->background.pixel = pScreen->whitePixel;
  698.  
  699.     pWin->borderIsPixel = TRUE;
  700.     pWin->border.pixel = pScreen->blackPixel;
  701.     pWin->borderWidth = 0;
  702.  
  703.     if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
  704.     return FALSE;
  705.  
  706.     if (disableBackingStore)
  707.     pScreen->backingStoreSupport = NotUseful;
  708.  
  709. #ifdef DO_SAVE_UNDERS
  710.     if ((pScreen->backingStoreSupport != NotUseful) &&
  711.     (pScreen->saveUnderSupport == NotUseful))
  712.     {
  713.     /*
  714.      * If the screen has backing-store but no save-unders, let the
  715.      * clients know we can support save-unders using backing-store.
  716.      */
  717.     pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
  718.     }
  719. #endif /* DO_SAVE_UNDERS */
  720.         
  721.     if (disableSaveUnders)
  722.     pScreen->saveUnderSupport = NotUseful;
  723.  
  724.     return TRUE;
  725. }
  726.  
  727. InitRootWindow(pWin)
  728.     WindowPtr pWin;
  729. {
  730.     ScreenPtr pScreen;
  731.  
  732.     pScreen = pWin->drawable.pScreen;
  733.     if (!(*pScreen->CreateWindow)(pWin))
  734.     return; /* XXX */
  735.     (*pScreen->PositionWindow)(pWin, 0, 0);
  736.  
  737.     pWin->cursorIsNone = FALSE;
  738.     pWin->optional->cursor = rootCursor;
  739.     rootCursor->refcnt++;
  740.     MakeRootTile(pWin);
  741.     pWin->backingStore = defaultBackingStore;
  742.     /* We SHOULD check for an error value here XXX */
  743.     (*pScreen->ChangeWindowAttributes)(pWin,
  744.                CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
  745.  
  746.     MapWindow(pWin, serverClient);
  747. }
  748.  
  749. /* Set the region to the intersection of the rectangle and the
  750.  * window's winSize.  The window is typically the parent of the
  751.  * window from which the region came.
  752.  */
  753.  
  754. ClippedRegionFromBox(pWin, Rgn, x, y, w, h)
  755.     register WindowPtr pWin;
  756.     RegionPtr Rgn;
  757.     register int x, y;
  758.     int w, h;
  759. {
  760.     register ScreenPtr pScreen = pWin->drawable.pScreen;
  761.     BoxRec box;
  762.  
  763.     box = *((* pScreen->RegionExtents)(&pWin->winSize));
  764.     /* we do these calculations to avoid overflows */
  765.     if (x > box.x1)
  766.     box.x1 = x;
  767.     if (y > box.y1)
  768.     box.y1 = y;
  769.     x += w;
  770.     if (x < box.x2)
  771.     box.x2 = x;
  772.     y += h;
  773.     if (y < box.y2)
  774.     box.y2 = y;
  775.     if (box.x1 > box.x2)
  776.     box.x2 = box.x1;
  777.     if (box.y1 > box.y2)
  778.     box.y2 = box.y1;
  779.     (* pScreen->RegionReset)(Rgn, &box);
  780.     (* pScreen->Intersect)(Rgn, Rgn, &pWin->winSize);
  781. }
  782.  
  783. WindowPtr
  784. RealChildHead(pWin)
  785.     register WindowPtr pWin;
  786. {
  787.     if (!pWin->parent &&
  788.     (screenIsSaved == SCREEN_SAVER_ON) &&
  789.     (HasSaverWindow (savedScreenInfo[pWin->drawable.pScreen->myNum].blanked)))
  790.     return (pWin->firstChild);
  791.     else
  792.     return (NullWindow);
  793. }
  794.  
  795. /*****
  796.  * CreateWindow
  797.  *    Makes a window in response to client request 
  798.  *****/
  799.  
  800. WindowPtr
  801. CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist,
  802.          depth, client, visual, error)
  803.     Window wid;
  804.     register WindowPtr pParent;
  805.     short x,y;
  806.     unsigned short w, h, bw;
  807.     unsigned short class;
  808.     register Mask vmask;
  809.     XID *vlist;
  810.     int depth;
  811.     ClientPtr client;
  812.     VisualID visual;
  813.     int *error;
  814. {
  815.     register WindowPtr pWin;
  816.     WindowPtr pHead;
  817.     register ScreenPtr pScreen;
  818.     xEvent event;
  819.     int idepth, ivisual;
  820.     Bool fOK;
  821.     DepthPtr pDepth;
  822.     PixmapFormatRec *format;
  823.     register WindowOptPtr ancwopt;
  824.  
  825.     if (class == CopyFromParent)
  826.     class = pParent->drawable.class;
  827.  
  828.     if ((class != InputOutput) && (class != InputOnly))
  829.     {
  830.     *error = BadValue;
  831.     client->errorValue = class;
  832.     return NullWindow;
  833.     }
  834.  
  835.     if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
  836.     {
  837.         *error = BadMatch;
  838.     return NullWindow;
  839.     }
  840.  
  841.     if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
  842.     {
  843.         *error = BadMatch;
  844.     return NullWindow;
  845.     }
  846.  
  847.     pScreen = pParent->drawable.pScreen;
  848.  
  849.     if ((class == InputOutput) && (depth == 0))
  850.         depth = pParent->drawable.depth;
  851.     ancwopt = pParent->optional;
  852.     if (!ancwopt)
  853.     ancwopt = FindWindowWithOptional(pParent)->optional;
  854.     if (visual == CopyFromParent)
  855.     visual = ancwopt->visual;
  856.  
  857.     /* Find out if the depth and visual are acceptable for this Screen */
  858.     if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
  859.     {
  860.     fOK = FALSE;
  861.     for(idepth = 0; idepth < pScreen->numDepths; idepth++)
  862.     {
  863.         pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
  864.         if ((depth == pDepth->depth) || (depth == 0))
  865.         {
  866.         for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
  867.         {
  868.             if (visual == pDepth->vids[ivisual])
  869.             {
  870.             fOK = TRUE;
  871.             break;
  872.             }
  873.         }
  874.         }
  875.     }
  876.     if (fOK == FALSE)
  877.     {
  878.         *error = BadMatch;
  879.         return NullWindow;
  880.     }
  881.     }
  882.  
  883.     if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
  884.     (class != InputOnly) &&
  885.     (depth != pParent->drawable.depth))
  886.     {
  887.         *error = BadMatch;
  888.         return NullWindow;
  889.     }
  890.  
  891.     if (((vmask & CWColormap) == 0) &&
  892.     (class != InputOnly) &&
  893.     ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
  894.     {
  895.     *error = BadMatch;
  896.         return NullWindow;
  897.     }
  898.  
  899.     pWin = AllocateWindow(pScreen);
  900.     if (!pWin)
  901.     {
  902.     *error = BadAlloc;
  903.         return NullWindow;
  904.     }
  905.     pWin->drawable = pParent->drawable;
  906.     pWin->drawable.depth = depth;
  907.     if (depth == pParent->drawable.depth)
  908.     pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
  909.     else
  910.     {
  911.     for (format = screenInfo.formats; format->depth != depth; format++)
  912.         ;
  913.     pWin->drawable.bitsPerPixel = format->bitsPerPixel;
  914.     }
  915.     if (class == InputOnly)
  916.         pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
  917.     pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  918.  
  919.     pWin->drawable.id = wid;
  920.     pWin->drawable.class = class;
  921.  
  922.     pWin->parent = pParent;
  923.     SetWindowToDefaults(pWin);
  924.  
  925.     if (visual != ancwopt->visual)
  926.     {
  927.     if (!MakeWindowOptional (pWin))
  928.     {
  929.         xfree (pWin);
  930.         *error = BadAlloc;
  931.         return NullWindow;
  932.     }
  933.     pWin->optional->visual = visual;
  934.     pWin->optional->colormap = None;
  935.     }
  936.  
  937.     pWin->borderWidth = bw;
  938.     pWin->backgroundState = None;
  939.  
  940.     pWin->borderIsPixel = pParent->borderIsPixel;
  941.     pWin->border = pParent->border;
  942.     if (pWin->borderIsPixel == FALSE)
  943.     pWin->border.pixmap->refcnt++;
  944.         
  945.     pWin->origin.x = x + (int)bw;
  946.     pWin->origin.y = y + (int)bw;
  947.     pWin->drawable.width = w;
  948.     pWin->drawable.height = h;
  949.     pWin->drawable.x = pParent->drawable.x + x + (int)bw;
  950.     pWin->drawable.y = pParent->drawable.y + y + (int)bw;
  951.  
  952.         /* set up clip list correctly for unobscured WindowPtr */
  953.     (* pScreen->RegionInit)(&pWin->clipList, NullBox, 1);
  954.     (* pScreen->RegionInit)(&pWin->borderClip, NullBox, 1);
  955.     (* pScreen->RegionInit)(&pWin->winSize, NullBox, 1);
  956.     (* pScreen->RegionInit)(&pWin->borderSize, NullBox, 1);
  957.  
  958.     pHead = RealChildHead(pParent);
  959.     if (pHead)
  960.     {
  961.     pWin->nextSib = pHead->nextSib;
  962.         if (pHead->nextSib)
  963.             pHead->nextSib->prevSib = pWin;
  964.     else
  965.         pParent->lastChild = pWin;
  966.         pHead->nextSib = pWin;
  967.     pWin->prevSib = pHead;
  968.     }
  969.     else
  970.     {
  971.         pWin->nextSib = pParent->firstChild;
  972.         if (pParent->firstChild)
  973.         pParent->firstChild->prevSib = pWin;
  974.         else
  975.             pParent->lastChild = pWin;
  976.     pParent->firstChild = pWin;
  977.     }
  978.  
  979.     SetWinSize (pWin);
  980.     SetBorderSize (pWin);
  981.  
  982.     /* We SHOULD check for an error value here XXX */
  983.     if (!(*pScreen->CreateWindow)(pWin))
  984.     {
  985.     *error = BadAlloc;
  986.     DeleteWindow(pWin, wid);
  987.     return NullWindow;
  988.     }
  989.     /* We SHOULD check for an error value here XXX */
  990.     (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
  991.  
  992.     if (!(vmask & CWEventMask))
  993.     RecalculateDeliverableEvents(pWin);
  994.  
  995.     if (vmask)
  996.         *error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
  997.     else
  998.     *error = Success;
  999.  
  1000.     if (*error != Success)
  1001.     {
  1002.         (void)EventSelectForWindow(pWin, client, (Mask)0); /* can't fail */
  1003.     DeleteWindow(pWin, wid);
  1004.     return NullWindow;
  1005.     }
  1006.     if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
  1007.     {
  1008.         XID value = defaultBackingStore;
  1009.     (void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
  1010.     }
  1011.  
  1012.     WindowHasNewCursor(pWin);
  1013.  
  1014.     if (SubSend(pParent))
  1015.     {
  1016.     event.u.u.type = CreateNotify;
  1017.     event.u.createNotify.window = wid;
  1018.     event.u.createNotify.parent = pParent->drawable.id;
  1019.     event.u.createNotify.x = x;
  1020.     event.u.createNotify.y = y;
  1021.     event.u.createNotify.width = w;
  1022.     event.u.createNotify.height = h;
  1023.     event.u.createNotify.borderWidth = bw;
  1024.     event.u.createNotify.override = pWin->overrideRedirect;
  1025.     DeliverEvents(pParent, &event, 1, NullWindow);        
  1026.     }
  1027.  
  1028.     return pWin;
  1029. }
  1030.  
  1031. static void
  1032. FreeWindowResources(pWin)
  1033.     register WindowPtr pWin;
  1034. {
  1035.     register ScreenPtr pScreen;
  1036.     void (* proc)();
  1037.  
  1038.     pScreen = pWin->drawable.pScreen;
  1039.  
  1040.     DeleteWindowFromAnySaveSet(pWin);
  1041.     DeleteWindowFromAnySelections(pWin);
  1042.     DeleteWindowFromAnyEvents(pWin, TRUE);
  1043.     proc = pScreen->RegionUninit;
  1044.     (* proc)(&pWin->clipList);
  1045.     (* proc)(&pWin->winSize);
  1046.     (* proc)(&pWin->borderClip);
  1047.     (* proc)(&pWin->borderSize);
  1048. #ifdef SHAPE
  1049.     if (wBoundingShape (pWin))
  1050.     (* pScreen->RegionDestroy)(wBoundingShape (pWin));
  1051.     if (wClipShape (pWin))
  1052.     (* pScreen->RegionDestroy)(wClipShape (pWin));
  1053. #endif
  1054.     if (pWin->borderIsPixel == FALSE)
  1055.     (* pScreen->DestroyPixmap)(pWin->border.pixmap);
  1056.     if (pWin->backgroundState == BackgroundPixmap)
  1057.     (* pScreen->DestroyPixmap)(pWin->background.pixmap);
  1058.  
  1059.     DeleteAllWindowProperties(pWin);
  1060.     /* We SHOULD check for an error value here XXX */
  1061.     (* pScreen->DestroyWindow)(pWin);
  1062.     DisposeWindowOptional (pWin);
  1063. }
  1064.  
  1065. static void
  1066. CrushTree(pWin)
  1067.     WindowPtr pWin;
  1068. {
  1069.     register WindowPtr pChild, pSib, pParent;
  1070.     Bool (* UnrealizeWindow)();
  1071.     xEvent event;
  1072.  
  1073.     if (!(pChild = pWin->firstChild))
  1074.         return;
  1075.     UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
  1076.     while (1)
  1077.     {
  1078.     if (pChild->firstChild)
  1079.     {
  1080.         pChild = pChild->firstChild;
  1081.         continue;
  1082.     }
  1083.     while (1)
  1084.     {
  1085.         pParent = pChild->parent;
  1086.         if (SubStrSend(pChild, pParent))
  1087.         {
  1088.         event.u.u.type = DestroyNotify;
  1089.         event.u.destroyNotify.window = pChild->drawable.id;
  1090.         DeliverEvents(pChild, &event, 1, NullWindow);        
  1091.         }
  1092.         FreeResource(pChild->drawable.id, RT_WINDOW);
  1093.         pSib = pChild->nextSib;
  1094. #ifdef DO_SAVE_UNDERS
  1095.         if (pChild->saveUnder && pChild->viewable)
  1096.         deltaSaveUndersViewable--;
  1097. #endif
  1098.         pChild->viewable = FALSE;
  1099.         if (pChild->realized)
  1100.         {
  1101.         pChild->realized = FALSE;
  1102.         (*UnrealizeWindow)(pChild);
  1103.         }
  1104.         FreeWindowResources(pChild);
  1105.         xfree(pChild);
  1106.         if (pChild = pSib)
  1107.         break;
  1108.         pChild = pParent;
  1109.         pChild->firstChild = NullWindow;
  1110.         pChild->lastChild = NullWindow;
  1111.         if (pChild == pWin)
  1112.         return;
  1113.     }
  1114.     }
  1115. }
  1116.     
  1117. /*****
  1118.  *  DeleteWindow
  1119.  *       Deletes child of window then window itself
  1120.  *****/
  1121.  
  1122. /*ARGSUSED*/
  1123. DeleteWindow(pWin, wid)
  1124.     register WindowPtr pWin;
  1125.     Window wid;
  1126. {
  1127.     register WindowPtr pParent;
  1128.     xEvent event;
  1129.  
  1130.     UnmapWindow(pWin, FALSE);
  1131.  
  1132.     CrushTree(pWin);
  1133.  
  1134.     pParent = pWin->parent;
  1135.     if (pParent && SubStrSend(pWin, pParent))
  1136.     {
  1137.     event.u.u.type = DestroyNotify;
  1138.     event.u.destroyNotify.window = pWin->drawable.id;
  1139.     DeliverEvents(pWin, &event, 1, NullWindow);        
  1140.     }
  1141.  
  1142.     FreeWindowResources(pWin);
  1143.     if (pParent)
  1144.     {
  1145.     if (pParent->firstChild == pWin)
  1146.             pParent->firstChild = pWin->nextSib;
  1147.     if (pParent->lastChild == pWin)
  1148.             pParent->lastChild = pWin->prevSib;
  1149.         if (pWin->nextSib)
  1150.             pWin->nextSib->prevSib = pWin->prevSib;
  1151.         if (pWin->prevSib)
  1152.             pWin->prevSib->nextSib = pWin->nextSib;
  1153.     }
  1154.     xfree(pWin);
  1155. }
  1156.  
  1157. /*ARGSUSED*/
  1158. DestroySubwindows(pWin, client)
  1159.     register WindowPtr pWin;
  1160.     ClientPtr client;
  1161. {
  1162.     /* XXX
  1163.      * The protocol is quite clear that each window should be
  1164.      * destroyed in turn, however, unmapping all of the first
  1165.      * eliminates most of the calls to ValidateTree.  So,
  1166.      * this implementation is incorrect in that all of the
  1167.      * UnmapNotifies occur before all of the DestroyNotifies.
  1168.      * If you care, simply delete the call to UnmapSubwindows.
  1169.      */
  1170.     UnmapSubwindows(pWin);
  1171.     while (pWin->lastChild)
  1172.     FreeResource(pWin->lastChild->drawable.id, RT_NONE);
  1173. }
  1174.  
  1175. /*****
  1176.  *  ChangeWindowAttributes
  1177.  *   
  1178.  *  The value-mask specifies which attributes are to be changed; the
  1179.  *  value-list contains one value for each one bit in the mask, from least
  1180.  *  to most significant bit in the mask.  
  1181.  *****/
  1182.  
  1183. int
  1184. ChangeWindowAttributes(pWin, vmask, vlist, client)
  1185.     register WindowPtr pWin;
  1186.     Mask vmask;
  1187.     XID *vlist;
  1188.     ClientPtr client;
  1189. {
  1190.     register Mask index;
  1191.     register XID *pVlist;
  1192.     PixmapPtr pPixmap;
  1193.     Pixmap pixID;
  1194.     CursorPtr pCursor;
  1195.     Cursor cursorID;
  1196.     WindowPtr pChild;
  1197.     Colormap cmap;
  1198.     ColormapPtr    pCmap;
  1199.     xEvent xE;
  1200.     int result;
  1201.     register ScreenPtr pScreen;
  1202.     Mask vmaskCopy = 0;
  1203.     register Mask tmask;
  1204.     unsigned int val;
  1205.     int error;
  1206.     Bool checkOptional = FALSE;
  1207.  
  1208.     if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
  1209.         return BadMatch;
  1210.  
  1211.     error = Success;
  1212.     pScreen = pWin->drawable.pScreen;
  1213.     pVlist = vlist;
  1214.     tmask = vmask;
  1215.     while (tmask)
  1216.     {
  1217.     index = (Mask) lowbit (tmask);
  1218.     tmask &= ~index;
  1219.     switch (index)
  1220.         {
  1221.       case CWBackPixmap:
  1222.         pixID = (Pixmap )*pVlist;
  1223.         pVlist++;
  1224.         if (pixID == None)
  1225.         {
  1226.         if (pWin->backgroundState == BackgroundPixmap)
  1227.             (* pScreen->DestroyPixmap)(pWin->background.pixmap);
  1228.         if (!pWin->parent)
  1229.                     MakeRootTile(pWin);
  1230.                 else
  1231.                     pWin->backgroundState = None;
  1232.         }
  1233.         else if (pixID == ParentRelative)
  1234.         {
  1235.         if (pWin->backgroundState == BackgroundPixmap)
  1236.             (* pScreen->DestroyPixmap)(pWin->background.pixmap);
  1237.         if (!pWin->parent)
  1238.             MakeRootTile(pWin);
  1239.         else
  1240.                 pWin->backgroundState = ParentRelative;
  1241.         /* Note that the parent's backgroundTile's refcnt is NOT
  1242.          * incremented. */
  1243.         }
  1244.             else
  1245.         {    
  1246.                 pPixmap = (PixmapPtr)LookupIDByType(pixID, RT_PIXMAP);
  1247.                 if (pPixmap != (PixmapPtr) NULL)
  1248.         {
  1249.                     if  ((pPixmap->drawable.depth != pWin->drawable.depth) ||
  1250.              (pPixmap->drawable.pScreen != pScreen))
  1251.             {
  1252.                         error = BadMatch;
  1253.             goto PatchUp;
  1254.             }
  1255.             if (pWin->backgroundState == BackgroundPixmap)
  1256.             (* pScreen->DestroyPixmap)(pWin->background.pixmap);
  1257.             pWin->backgroundState = BackgroundPixmap;
  1258.             pWin->background.pixmap = pPixmap;
  1259.             pPixmap->refcnt++;
  1260.         }
  1261.             else
  1262.         {
  1263.             error = BadPixmap;
  1264.             client->errorValue = pixID;
  1265.             goto PatchUp;
  1266.         }
  1267.         }
  1268.         break;
  1269.       case CWBackPixel:
  1270.         if (pWin->backgroundState == BackgroundPixmap)
  1271.         (* pScreen->DestroyPixmap)(pWin->background.pixmap);
  1272.         pWin->backgroundState = BackgroundPixel;
  1273.         pWin->background.pixel = (CARD32 ) *pVlist;
  1274.                /* background pixel overrides background pixmap,
  1275.               so don't let the ddx layer see both bits */
  1276.             vmaskCopy &= ~CWBackPixmap;
  1277.         pVlist++;
  1278.         break;
  1279.       case CWBorderPixmap:
  1280.         pixID = (Pixmap ) *pVlist;
  1281.         pVlist++;
  1282.         if (pixID == CopyFromParent)
  1283.         {
  1284.         if (!pWin->parent ||
  1285.             (pWin->drawable.depth != pWin->parent->drawable.depth))
  1286.         {
  1287.             error = BadMatch;
  1288.             goto PatchUp;
  1289.         }
  1290.         if (pWin->borderIsPixel == FALSE)
  1291.             (* pScreen->DestroyPixmap)(pWin->border.pixmap);
  1292.         pWin->border = pWin->parent->border;
  1293.         if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
  1294.         {
  1295.             index = CWBorderPixel;
  1296.         }
  1297.                 else
  1298.         {
  1299.             pWin->parent->border.pixmap->refcnt++;
  1300.         }
  1301.         }
  1302.         else
  1303.         {    
  1304.         pPixmap = (PixmapPtr)LookupIDByType(pixID, RT_PIXMAP);
  1305.         if (pPixmap)
  1306.         {
  1307.                     if  ((pPixmap->drawable.depth != pWin->drawable.depth) ||
  1308.              (pPixmap->drawable.pScreen != pScreen))
  1309.             {
  1310.             error = BadMatch;
  1311.             goto PatchUp;
  1312.             }
  1313.             if (pWin->borderIsPixel == FALSE)
  1314.             (* pScreen->DestroyPixmap)(pWin->border.pixmap);
  1315.             pWin->borderIsPixel = FALSE;
  1316.             pWin->border.pixmap = pPixmap;
  1317.             pPixmap->refcnt++;
  1318.         }
  1319.                 else
  1320.         {
  1321.             error = BadPixmap;
  1322.             client->errorValue = pixID;
  1323.             goto PatchUp;
  1324.         }
  1325.         }
  1326.         break;
  1327.       case CWBorderPixel:
  1328.         if (pWin->borderIsPixel == FALSE)
  1329.         (* pScreen->DestroyPixmap)(pWin->border.pixmap);
  1330.         pWin->borderIsPixel = TRUE;
  1331.             pWin->border.pixel = (CARD32) *pVlist;
  1332.             /* border pixel overrides border pixmap,
  1333.                so don't let the ddx layer see both bits */
  1334.         vmaskCopy &= ~CWBorderPixmap;
  1335.         pVlist++;
  1336.             break;
  1337.       case CWBitGravity:
  1338.         val = (CARD8 )*pVlist;
  1339.         pVlist++;
  1340.         if (val > StaticGravity)
  1341.         {
  1342.         error = BadValue;
  1343.         client->errorValue = val;
  1344.         goto PatchUp;
  1345.         }
  1346.         pWin->bitGravity = val;
  1347.         break;
  1348.       case CWWinGravity:
  1349.         val = (CARD8 )*pVlist;
  1350.         pVlist++;
  1351.         if (val > StaticGravity)
  1352.         {
  1353.         error = BadValue;
  1354.         client->errorValue = val;
  1355.         goto PatchUp;
  1356.         }
  1357.         pWin->winGravity = val;
  1358.         break;
  1359.       case CWBackingStore:
  1360.         val = (CARD8 )*pVlist;
  1361.         pVlist++;
  1362.         if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
  1363.         {
  1364.         error = BadValue;
  1365.         client->errorValue = val;
  1366.         goto PatchUp;
  1367.         }
  1368.         pWin->backingStore = val;
  1369.         break;
  1370.       case CWBackingPlanes:
  1371.         if (pWin->optional || ((CARD32)*pVlist != ~0L)) {
  1372.         if (!pWin->optional && !MakeWindowOptional (pWin))
  1373.         {
  1374.             error = BadAlloc;
  1375.             goto PatchUp;
  1376.         }
  1377.         pWin->optional->backingBitPlanes = (CARD32) *pVlist;
  1378.         if ((CARD32)*pVlist == ~0L)
  1379.             checkOptional = TRUE;
  1380.         }
  1381.         pVlist++;
  1382.         break;
  1383.       case CWBackingPixel:
  1384.         if (pWin->optional || (CARD32) *pVlist) {
  1385.         if (!pWin->optional && !MakeWindowOptional (pWin))
  1386.         {
  1387.             error = BadAlloc;
  1388.             goto PatchUp;
  1389.         }
  1390.         pWin->optional->backingPixel = (CARD32) *pVlist;
  1391.         if (!*pVlist)
  1392.             checkOptional = TRUE;
  1393.         }
  1394.         pVlist++;
  1395.         break;
  1396.       case CWSaveUnder:
  1397.         val = (BOOL) *pVlist;
  1398.         pVlist++;
  1399.         if ((val != xTrue) && (val != xFalse))
  1400.         {
  1401.         error = BadValue;
  1402.         client->errorValue = val;
  1403.         goto PatchUp;
  1404.         }
  1405. #ifdef DO_SAVE_UNDERS
  1406.         if ((pWin->saveUnder != val) && (pWin->viewable) &&
  1407.         DO_SAVE_UNDERS(pWin))
  1408.         {
  1409.         /*
  1410.          * Re-check all siblings and inferiors for obscurity or
  1411.          * exposition (hee hee).
  1412.          */
  1413.         if (pWin->saveUnder)
  1414.             deltaSaveUndersViewable--;
  1415.         else
  1416.             deltaSaveUndersViewable++;
  1417.         pWin->saveUnder = val;
  1418.         if (ChangeSaveUnder(pWin, pWin->nextSib))
  1419.             DoChangeSaveUnder(pWin->parent, pWin->nextSib);
  1420.         }
  1421.         else
  1422.         {
  1423.         pWin->saveUnder = val;
  1424.         }
  1425. #else
  1426.         pWin->saveUnder = val;
  1427. #endif /* DO_SAVE_UNDERS */
  1428.         break;
  1429.       case CWEventMask:
  1430.         result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
  1431.         if (result)
  1432.         {
  1433.         error = result;
  1434.         goto PatchUp;
  1435.         }
  1436.         pVlist++;
  1437.         break;
  1438.       case CWDontPropagate:
  1439.         result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
  1440.                         &checkOptional);
  1441.         if (result)
  1442.         {
  1443.         error = result;
  1444.         goto PatchUp;
  1445.         }
  1446.         pVlist++;
  1447.         break;
  1448.       case CWOverrideRedirect:
  1449.         val = (BOOL ) *pVlist;
  1450.         pVlist++;
  1451.         if ((val != xTrue) && (val != xFalse))
  1452.         {
  1453.         error = BadValue;
  1454.         client->errorValue = val;
  1455.         goto PatchUp;
  1456.         }
  1457.         pWin->overrideRedirect = val;
  1458.         break;
  1459.       case CWColormap:
  1460.         cmap = (Colormap) *pVlist;
  1461.         pVlist++;
  1462.         if (cmap == CopyFromParent)
  1463.         {
  1464.         if (pWin->parent &&
  1465.             (!pWin->optional ||
  1466.               pWin->optional->visual == wVisual (pWin->parent)))
  1467.         {
  1468.             cmap = wColormap (pWin->parent);
  1469.         }
  1470.         else
  1471.             cmap = None;
  1472.         }
  1473.         if (cmap == None)
  1474.         {
  1475.         error = BadMatch;
  1476.         goto PatchUp;
  1477.         }
  1478.         pCmap = (ColormapPtr)LookupIDByType(cmap, RT_COLORMAP);
  1479.         if (!pCmap)
  1480.         {
  1481.         error = BadColor;
  1482.         client->errorValue = cmap;
  1483.         goto PatchUp;
  1484.         }
  1485.         if (pCmap->pVisual->vid != wVisual (pWin))
  1486.         {
  1487.         error = BadMatch;
  1488.         goto PatchUp;
  1489.         }
  1490.         if (cmap != wColormap (pWin))
  1491.         {
  1492.         if (!pWin->optional)
  1493.         {
  1494.             if (!MakeWindowOptional (pWin))
  1495.             {
  1496.             error = BadAlloc;
  1497.             goto PatchUp;
  1498.             }
  1499.         }
  1500.         else if (pWin->parent && cmap == wColormap (pWin->parent))
  1501.             checkOptional = TRUE;
  1502.  
  1503.         /*
  1504.          * propagate the original colormap to any children
  1505.          * inheriting it
  1506.          */
  1507.  
  1508.         for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
  1509.         {
  1510.             if (!pChild->optional && !MakeWindowOptional (pChild))
  1511.             {
  1512.             error = BadAlloc;
  1513.             goto PatchUp;
  1514.             }
  1515.         }
  1516.  
  1517.         pWin->optional->colormap = cmap;
  1518.  
  1519.         /*
  1520.          * check on any children now matching the new colormap
  1521.          */
  1522.  
  1523.         for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
  1524.         {
  1525.             if (pChild->optional->colormap == cmap)
  1526.             CheckWindowOptionalNeed (pChild);
  1527.         }
  1528.  
  1529.         xE.u.u.type = ColormapNotify;
  1530.         xE.u.colormap.window = pWin->drawable.id;
  1531.         xE.u.colormap.colormap = cmap;
  1532.         xE.u.colormap.new = xTrue;
  1533.         xE.u.colormap.state = IsMapInstalled(cmap, pWin);
  1534.         DeliverEvents(pWin, &xE, 1, NullWindow);
  1535.         }
  1536.         break;
  1537.       case CWCursor:
  1538.         cursorID = (Cursor ) *pVlist;
  1539.         pVlist++;
  1540.         /*
  1541.          * install the new
  1542.          */
  1543.         if ( cursorID == None)
  1544.         {
  1545.             if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
  1546.             pCursor = rootCursor;
  1547.             else
  1548.             pCursor = (CursorPtr) None;
  1549.         }
  1550.         else
  1551.         {
  1552.             pCursor = (CursorPtr)LookupIDByType(cursorID, RT_CURSOR);
  1553.             if (!pCursor)
  1554.             {
  1555.             error = BadCursor;
  1556.             client->errorValue = cursorID;
  1557.             goto PatchUp;
  1558.             }
  1559.         }
  1560.  
  1561.         if (pCursor != wCursor (pWin))
  1562.         {
  1563.             /*
  1564.               * patch up child windows so they don't lose cursors.
  1565.               */
  1566.  
  1567.             for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
  1568.         {
  1569.             if (!pChild->optional && !pChild->cursorIsNone &&
  1570.             !MakeWindowOptional (pChild))
  1571.             {
  1572.             error = BadAlloc;
  1573.             goto PatchUp;
  1574.             }
  1575.             }
  1576.  
  1577.         if (pCursor == (CursorPtr) None)
  1578.         {
  1579.             pWin->cursorIsNone = TRUE;
  1580.             if (pWin->optional)
  1581.             {
  1582.             if (pWin->optional->cursor)
  1583.                 FreeCursor (pWin->optional->cursor, (Cursor)0);
  1584.             pWin->optional->cursor = (CursorPtr) None;
  1585.             checkOptional = TRUE;
  1586.             }
  1587.         } else {
  1588.             if (!pWin->optional)
  1589.             {
  1590.             if (!MakeWindowOptional (pWin))
  1591.             {
  1592.                 error = BadAlloc;
  1593.                 goto PatchUp;
  1594.             }
  1595.             }
  1596.             else if (pWin->parent && pCursor == wCursor (pWin->parent))
  1597.             checkOptional = TRUE;
  1598.             if (pWin->optional->cursor != (CursorPtr) None)
  1599.             FreeCursor (pWin->optional->cursor, (Cursor)0);
  1600.             pWin->optional->cursor = pCursor;
  1601.             pCursor->refcnt++;
  1602.             pWin->cursorIsNone = FALSE;
  1603.             /*
  1604.              * check on any children now matching the new cursor
  1605.              */
  1606.  
  1607.             for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
  1608.             {
  1609.             if (pChild->optional &&
  1610.                 (pChild->optional->cursor == pCursor))
  1611.                 CheckWindowOptionalNeed (pChild);
  1612.             }
  1613.         }
  1614.  
  1615.             WindowHasNewCursor( pWin);
  1616.         }
  1617.         break;
  1618.           default:
  1619.         error = BadValue;
  1620.         client->errorValue = vmask;
  1621.         goto PatchUp;
  1622.       }
  1623.       vmaskCopy |= index;
  1624.     }
  1625. PatchUp:
  1626.     if (checkOptional)
  1627.     CheckWindowOptionalNeed (pWin);
  1628.  
  1629.         /* We SHOULD check for an error value here XXX */
  1630.     (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
  1631.  
  1632.     /* 
  1633.         If the border contents have changed, redraw the border. 
  1634.     Note that this has to be done AFTER pScreen->ChangeWindowAttributes
  1635.         for the tile to be rotated, and the correct function selected.
  1636.     */
  1637.     if ((vmaskCopy & (CWBorderPixel | CWBorderPixmap))
  1638.     && pWin->viewable && HasBorder (pWin))
  1639.     {
  1640.     RegionRec exposed;
  1641.  
  1642.     (* pScreen->RegionInit)(&exposed, NullBox, 0);
  1643.         (* pScreen->Subtract)(&exposed, &pWin->borderClip, &pWin->winSize);
  1644.     (*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
  1645.         (* pScreen->RegionUninit)(&exposed);
  1646.     }
  1647.     return error;
  1648. }
  1649.  
  1650.  
  1651. /*****
  1652.  * GetWindowAttributes
  1653.  *    Notice that this is different than ChangeWindowAttributes
  1654.  *****/
  1655.  
  1656. GetWindowAttributes(pWin, client)
  1657.     register WindowPtr pWin;
  1658.     ClientPtr client;
  1659. {
  1660.     xGetWindowAttributesReply wa;
  1661.  
  1662.     wa.type = X_Reply;
  1663.     wa.bitGravity = pWin->bitGravity;
  1664.     wa.winGravity = pWin->winGravity;
  1665.     wa.backingStore  = pWin->backingStore;
  1666.     wa.length = (sizeof(xGetWindowAttributesReply) -
  1667.          sizeof(xGenericReply)) >> 2;
  1668.     wa.sequenceNumber = client->sequence;
  1669.     wa.backingBitPlanes =  wBackingBitPlanes (pWin);
  1670.     wa.backingPixel =  wBackingPixel (pWin);
  1671.     wa.saveUnder = (BOOL)pWin->saveUnder;
  1672.     wa.override = pWin->overrideRedirect;
  1673.     if (!pWin->mapped)
  1674.         wa.mapState = IsUnmapped;
  1675.     else if (pWin->realized)
  1676.         wa.mapState = IsViewable;
  1677.     else
  1678.         wa.mapState = IsUnviewable;
  1679.  
  1680.     wa.colormap =  wColormap (pWin);
  1681.     wa.mapInstalled = (wa.colormap == None) ? xFalse
  1682.                         : IsMapInstalled(wa.colormap, pWin);
  1683.  
  1684.     wa.yourEventMask = EventMaskForClient(pWin, client);
  1685.     wa.allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
  1686.     wa.doNotPropagateMask = wDontPropagateMask (pWin);
  1687.     wa.class = pWin->drawable.class;
  1688.     wa.visualID = wVisual (pWin);
  1689.  
  1690.     WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
  1691. }
  1692.  
  1693.  
  1694. static WindowPtr
  1695. MoveWindowInStack(pWin, pNextSib)
  1696.     register WindowPtr pWin, pNextSib;
  1697. {
  1698.     register WindowPtr pParent = pWin->parent;
  1699.     WindowPtr pFirstChange = pWin; /* highest window where list changes */
  1700.  
  1701.     if (pWin->nextSib != pNextSib)
  1702.     {
  1703.         if (!pNextSib)        /* move to bottom */
  1704.     {
  1705.             if (pParent->firstChild == pWin)
  1706.                 pParent->firstChild = pWin->nextSib;
  1707.         /* if (pWin->nextSib) */     /* is always True: pNextSib == NULL
  1708.                           * and pWin->nextSib != pNextSib
  1709.                       * therefore pWin->nextSib != NULL */
  1710.         pFirstChange = pWin->nextSib;
  1711.         pWin->nextSib->prevSib = pWin->prevSib;
  1712.         if (pWin->prevSib)
  1713.                 pWin->prevSib->nextSib = pWin->nextSib;
  1714.             pParent->lastChild->nextSib = pWin;
  1715.             pWin->prevSib = pParent->lastChild;
  1716.             pWin->nextSib = NullWindow;
  1717.             pParent->lastChild = pWin;
  1718.     }
  1719.         else if (pParent->firstChild == pNextSib) /* move to top */
  1720.         {
  1721.         pFirstChange = pWin;
  1722.         if (pParent->lastChild == pWin)
  1723.                pParent->lastChild = pWin->prevSib;
  1724.         if (pWin->nextSib)
  1725.         pWin->nextSib->prevSib = pWin->prevSib;
  1726.         if (pWin->prevSib)
  1727.                 pWin->prevSib->nextSib = pWin->nextSib;
  1728.         pWin->nextSib = pParent->firstChild;
  1729.         pWin->prevSib = (WindowPtr ) NULL;
  1730.         pNextSib->prevSib = pWin;
  1731.         pParent->firstChild = pWin;
  1732.     }
  1733.         else            /* move in middle of list */
  1734.         {
  1735.         WindowPtr pOldNext = pWin->nextSib;
  1736.  
  1737.         pFirstChange = NullWindow;
  1738.             if (pParent->firstChild == pWin)
  1739.                 pFirstChange = pParent->firstChild = pWin->nextSib;
  1740.         if (pParent->lastChild == pWin) {
  1741.            pFirstChange = pWin;
  1742.                pParent->lastChild = pWin->prevSib;
  1743.         }
  1744.         if (pWin->nextSib)
  1745.         pWin->nextSib->prevSib = pWin->prevSib;
  1746.         if (pWin->prevSib)
  1747.                 pWin->prevSib->nextSib = pWin->nextSib;
  1748.             pWin->nextSib = pNextSib;
  1749.             pWin->prevSib = pNextSib->prevSib;
  1750.         if (pNextSib->prevSib)
  1751.                 pNextSib->prevSib->nextSib = pWin;
  1752.             pNextSib->prevSib = pWin;
  1753.         if (!pFirstChange) {             /* do we know it yet? */
  1754.             pFirstChange = pParent->firstChild;  /* no, search from top */
  1755.             while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
  1756.              pFirstChange = pFirstChange->nextSib;
  1757.         }
  1758.     }
  1759.     }
  1760.  
  1761.     return( pFirstChange );
  1762. }
  1763.  
  1764. RegionPtr
  1765. CreateUnclippedWinSize (pWin)
  1766.     register WindowPtr   pWin;
  1767. {
  1768.     RegionPtr    pRgn;
  1769.     BoxRec    box;
  1770.  
  1771.     box.x1 = pWin->drawable.x;
  1772.     box.y1 = pWin->drawable.y;
  1773.     box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
  1774.     box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
  1775.     pRgn = (*pWin->drawable.pScreen->RegionCreate) (&box, 1);
  1776. #ifdef SHAPE
  1777.     if (wBoundingShape (pWin) || wClipShape (pWin)) {
  1778.         ScreenPtr    pScreen = pWin->drawable.pScreen;
  1779.  
  1780.     (*pScreen->TranslateRegion)
  1781.         (pRgn, - pWin->drawable.x, - pWin->drawable.y);
  1782.     if (wBoundingShape (pWin))
  1783.         (*pScreen->Intersect)
  1784.         (pRgn, pRgn, wBoundingShape (pWin));
  1785.     if (wClipShape (pWin))
  1786.         (*pScreen->Intersect)
  1787.         (pRgn, pRgn, wClipShape (pWin));
  1788.     (*pScreen->TranslateRegion)
  1789.         (pRgn, pWin->drawable.x, pWin->drawable.y);
  1790.     }
  1791. #endif
  1792.     return pRgn;
  1793. }
  1794.  
  1795. static void
  1796. SetWinSize (pWin)
  1797.     register WindowPtr pWin;
  1798. {
  1799.     ClippedRegionFromBox(pWin->parent, &pWin->winSize,
  1800.              pWin->drawable.x, pWin->drawable.y,
  1801.               (int)pWin->drawable.width,
  1802.               (int)pWin->drawable.height);
  1803. #ifdef SHAPE
  1804.     if (wBoundingShape (pWin) || wClipShape (pWin)) {
  1805.         ScreenPtr    pScreen = pWin->drawable.pScreen;
  1806.  
  1807.     (*pScreen->TranslateRegion)
  1808.         (&pWin->winSize, - pWin->drawable.x, - pWin->drawable.y);
  1809.     if (wBoundingShape (pWin))
  1810.         (*pScreen->Intersect)
  1811.         (&pWin->winSize, &pWin->winSize, wBoundingShape (pWin));
  1812.     if (wClipShape (pWin))
  1813.         (*pScreen->Intersect)
  1814.         (&pWin->winSize, &pWin->winSize, wClipShape (pWin));
  1815.     (*pScreen->TranslateRegion)
  1816.         (&pWin->winSize, pWin->drawable.x, pWin->drawable.y);
  1817.     }
  1818. #endif
  1819. }
  1820.  
  1821. static void
  1822. SetBorderSize (pWin)
  1823.     register WindowPtr pWin;
  1824. {
  1825.     int    bw;
  1826.  
  1827.     if (HasBorder (pWin)) {
  1828.     bw = wBorderWidth (pWin);
  1829.     ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
  1830.         pWin->drawable.x - bw, pWin->drawable.y - bw,
  1831.         (int)(pWin->drawable.width + (bw<<1)),
  1832.          (int)(pWin->drawable.height + (bw<<1)));
  1833. #ifdef SHAPE
  1834.         if (wBoundingShape (pWin)) {
  1835.             ScreenPtr    pScreen = pWin->drawable.pScreen;
  1836.  
  1837.         (*pScreen->TranslateRegion)
  1838.             (&pWin->borderSize, - pWin->drawable.x, - pWin->drawable.y);
  1839.         (*pScreen->Intersect)
  1840.             (&pWin->borderSize, &pWin->borderSize, wBoundingShape (pWin));
  1841.         (*pScreen->TranslateRegion)
  1842.             (&pWin->borderSize, pWin->drawable.x, pWin->drawable.y);
  1843.         (*pScreen->Union) (&pWin->borderSize,
  1844.                    &pWin->borderSize, &pWin->winSize);
  1845.         }
  1846. #endif
  1847.     } else {
  1848.     (* pWin->drawable.pScreen->RegionCopy)(&pWin->borderSize,
  1849.                            &pWin->winSize);
  1850.     }
  1851. }
  1852.  
  1853. static void
  1854. MoveWindow(pWin, x, y, pNextSib, kind)
  1855.     register WindowPtr pWin;
  1856.     short x,y;
  1857.     WindowPtr pNextSib;
  1858.     VTKind kind;
  1859. {
  1860.     WindowPtr pParent;
  1861.     Bool WasViewable = (Bool)(pWin->viewable);
  1862.     short bw;
  1863.     RegionPtr oldRegion;
  1864.     DDXPointRec oldpt;
  1865.     Bool anyMarked;
  1866.     register ScreenPtr pScreen;
  1867.     WindowPtr windowToValidate;
  1868. #ifdef DO_SAVE_UNDERS
  1869.     Bool dosave = FALSE;
  1870. #endif
  1871.  
  1872.     /* if this is a root window, can't be moved */
  1873.     if (!(pParent = pWin->parent))
  1874.        return ;
  1875.     pScreen = pWin->drawable.pScreen;
  1876.     bw = wBorderWidth (pWin);
  1877.  
  1878.     oldpt.x = pWin->drawable.x;
  1879.     oldpt.y = pWin->drawable.y;
  1880.     if (WasViewable)
  1881.     {
  1882.         oldRegion = (* pScreen->RegionCreate)(NullBox, 1);
  1883.         (* pScreen->RegionCopy)(oldRegion, &pWin->borderClip);
  1884.     anyMarked = MarkOverlappedWindows(pWin, pWin);
  1885.     }
  1886.     pWin->origin.x = x + (int)bw;
  1887.     pWin->origin.y = y + (int)bw;
  1888.     x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
  1889.     y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
  1890.  
  1891.     SetWinSize (pWin);
  1892.     SetBorderSize (pWin);
  1893.  
  1894.     (* pScreen->PositionWindow)(pWin, x, y);
  1895.  
  1896.     windowToValidate = MoveWindowInStack(pWin, pNextSib);
  1897.  
  1898.     ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
  1899.  
  1900.     if (WasViewable)
  1901.     {
  1902.  
  1903.         anyMarked |= MarkOverlappedWindows(pWin, windowToValidate);
  1904. #ifdef DO_SAVE_UNDERS
  1905.     if (DO_SAVE_UNDERS(pWin))
  1906.     {
  1907.         if (pWin->saveUnder)
  1908.         dosave = ChangeSaveUnder(pWin, windowToValidate);
  1909.         else
  1910.         dosave = CheckSaveUnder(pWin);
  1911.     }
  1912. #endif /* DO_SAVE_UNDERS */
  1913.  
  1914.     if (anyMarked)
  1915.     {
  1916.         (* pScreen->ValidateTree)(pParent, NullWindow, kind);
  1917.         (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
  1918.         (* pScreen->RegionDestroy)(oldRegion);
  1919.         /* XXX need to retile border if ParentRelative origin */
  1920.         HandleExposures(pParent);
  1921.     }
  1922. #ifdef DO_SAVE_UNDERS
  1923.     if (dosave)
  1924.         DoChangeSaveUnder(pWin->parent, windowToValidate);
  1925. #endif /* DO_SAVE_UNDERS */
  1926.     }
  1927.     if (pWin->realized)
  1928.     WindowsRestructured ();
  1929. }
  1930.  
  1931. void
  1932. GravityTranslate (x, y, oldx, oldy, dw, dh, gravity, destx, desty)
  1933.     register int x, y;        /* new window position */
  1934.     int        oldx, oldy;    /* old window position */
  1935.     int        dw, dh;
  1936.     unsigned    gravity;
  1937.     register int *destx, *desty;    /* position relative to gravity */
  1938. {
  1939.     switch (gravity) {
  1940.     case NorthGravity:
  1941.     *destx = x + (dw >> 1);
  1942.     *desty = y;
  1943.     break;
  1944.     case NorthEastGravity:
  1945.     *destx = x + dw;
  1946.     *desty = y;
  1947.     break;
  1948.     case WestGravity:
  1949.     *destx = x;
  1950.     *desty = y + (dh >> 1);
  1951.     break;
  1952.     case CenterGravity:
  1953.     *destx = x + (dw >> 1);
  1954.     *desty = y + (dh >> 1);
  1955.     break;
  1956.     case EastGravity:
  1957.     *destx = x + dw;
  1958.     *desty = y + (dh >> 1);
  1959.     break;
  1960.     case SouthWestGravity:
  1961.     *destx = x;
  1962.     *desty = y + dh;
  1963.     break;
  1964.     case SouthGravity:
  1965.     *destx = x + (dw >> 1);
  1966.     *desty = y + dh;
  1967.     break;
  1968.     case SouthEastGravity:
  1969.     *destx = x + dw;
  1970.     *desty = y + dh;
  1971.     break;
  1972.     case StaticGravity:
  1973.     *destx = oldx;
  1974.     *desty = oldy;
  1975.     break;
  1976.     default:
  1977.     *destx = x;
  1978.     *desty = y;
  1979.     break;
  1980.     }
  1981. }
  1982.  
  1983. /* XXX need to retile border on each window with ParentRelative origin */
  1984. static void
  1985. ResizeChildrenWinSize(pWin, dx, dy, dw, dh)
  1986.     register WindowPtr pWin;
  1987.     int dx, dy, dw, dh;
  1988. {
  1989.     register ScreenPtr pScreen;
  1990.     register WindowPtr pSib, pChild;
  1991.     Bool resized = (dw || dh);
  1992.  
  1993.     pScreen = pWin->drawable.pScreen;
  1994.  
  1995.     for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
  1996.     {
  1997.     if (resized && (pSib->winGravity > NorthWestGravity))
  1998.     {
  1999.         int cwsx, cwsy;
  2000.  
  2001.         cwsx = pSib->origin.x;
  2002.         cwsy = pSib->origin.y;
  2003.         GravityTranslate (cwsx, cwsy, cwsx - dx, cwsx - dy, dw, dh,
  2004.             pSib->winGravity, &cwsx, &cwsy);
  2005.         if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
  2006.         {
  2007.         xEvent event;
  2008.  
  2009.         event.u.u.type = GravityNotify;
  2010.         event.u.gravity.window = pSib->drawable.id;
  2011.         event.u.gravity.x = cwsx - wBorderWidth (pSib);
  2012.         event.u.gravity.y = cwsy - wBorderWidth (pSib);
  2013.         DeliverEvents (pSib, &event, 1, NullWindow);
  2014.         pSib->origin.x = cwsx;
  2015.         pSib->origin.y = cwsy;
  2016.         }
  2017.     }
  2018.     pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
  2019.     pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
  2020.     SetWinSize (pSib);
  2021.     SetBorderSize (pSib);
  2022.     (* pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
  2023.     if (pChild = pSib->firstChild)
  2024.     {
  2025.         while (1)
  2026.         {
  2027.         pChild->drawable.x = pChild->parent->drawable.x +
  2028.                      pChild->origin.x;
  2029.         pChild->drawable.y = pChild->parent->drawable.y +
  2030.                      pChild->origin.y;
  2031.         SetWinSize (pChild);
  2032.         SetBorderSize (pChild);
  2033.         (* pScreen->PositionWindow)(pChild,
  2034.                     pChild->drawable.x, pChild->drawable.y);
  2035.         if (pChild->firstChild)
  2036.         {
  2037.             pChild = pChild->firstChild;
  2038.             continue;
  2039.         }
  2040.         while (!pChild->nextSib && (pChild != pSib))
  2041.             pChild = pChild->parent;
  2042.         if (pChild == pSib)
  2043.             break;
  2044.         pChild = pChild->nextSib;
  2045.         }
  2046.     }
  2047.     }
  2048. }
  2049.  
  2050. /*
  2051.  * pValid is a region of the screen which has been
  2052.  * successfully copied -- recomputed exposed regions for affected windows
  2053.  */
  2054.  
  2055. static int
  2056. RecomputeExposures (pWin, pValid)
  2057.     register WindowPtr    pWin;
  2058.     RegionPtr    pValid;
  2059. {
  2060.     register ScreenPtr    pScreen;
  2061.  
  2062.     if (pWin->valdata)
  2063.     {
  2064.     pScreen = pWin->drawable.pScreen;
  2065.     /*
  2066.      * compute exposed regions of this window
  2067.      */
  2068.     (*pScreen->Subtract)(&pWin->valdata->after.exposed, &pWin->clipList, pValid);
  2069.     /*
  2070.      * compute exposed regions of the border
  2071.      */
  2072.     (*pScreen->Subtract)(&pWin->valdata->after.borderExposed,
  2073.                  &pWin->borderClip, &pWin->winSize);
  2074.     (*pScreen->Subtract)(&pWin->valdata->after.borderExposed,
  2075.                  &pWin->valdata->after.borderExposed, pValid);
  2076.     return WT_WALKCHILDREN;
  2077.     }
  2078.     return WT_NOMATCH;
  2079. }
  2080.  
  2081.  
  2082. static void
  2083. SlideAndSizeWindow(pWin, x, y, w, h, pSib)
  2084.     register WindowPtr pWin;
  2085.     short x,y;
  2086.     unsigned short w, h;
  2087.     WindowPtr pSib;
  2088. {
  2089.     WindowPtr pParent;
  2090.     Bool WasViewable = (Bool)(pWin->viewable);
  2091.     unsigned short width = pWin->drawable.width,
  2092.                    height = pWin->drawable.height;
  2093.     short oldx = pWin->drawable.x,
  2094.           oldy = pWin->drawable.y;
  2095.     int bw = wBorderWidth (pWin);
  2096.     short dw, dh;
  2097.     DDXPointRec oldpt;
  2098.     RegionPtr oldRegion;
  2099.     Bool anyMarked;
  2100.     register ScreenPtr pScreen;
  2101.     WindowPtr pFirstChange;
  2102.     register WindowPtr pChild;
  2103.     RegionPtr    gravitate[StaticGravity + 1];
  2104.     register unsigned g;
  2105.     int        nx, ny;        /* destination x,y */
  2106.     int        newx, newy;    /* new inner window position */
  2107.     RegionPtr    pRegion;
  2108.     RegionPtr    destClip;    /* portions of destination already written */
  2109.     RegionPtr    oldWinClip;    /* old clip list for window */
  2110.     RegionPtr    borderVisible = NullRegion; /* visible area of the border */
  2111.     RegionPtr    bsExposed = NullRegion;        /* backing store exposures */
  2112.     Bool    shrunk = FALSE; /* shrunk in an inner dimension */
  2113. #ifdef DO_SAVE_UNDERS
  2114.     Bool    dosave = FALSE;
  2115. #endif
  2116.  
  2117.     /* if this is a root window, can't be resized */
  2118.     if (!(pParent = pWin->parent))
  2119.         return ;
  2120.  
  2121.     pScreen = pWin->drawable.pScreen;
  2122.     newx = pParent->drawable.x + x + bw;
  2123.     newy = pParent->drawable.y + y + bw;
  2124.     if (WasViewable)
  2125.     {
  2126.     anyMarked = FALSE;
  2127.     /*
  2128.      * save the visible region of the window
  2129.      */
  2130.     oldRegion = (*pScreen->RegionCreate) (NullBox, 1);
  2131.     (*pScreen->RegionCopy) (oldRegion, &pWin->winSize);
  2132.  
  2133.     /*
  2134.      * catagorize child windows into regions to be moved
  2135.      */
  2136.     for (g = 0; g <= StaticGravity; g++)
  2137.         gravitate[g] = (RegionPtr) NULL;
  2138.     for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
  2139.     {
  2140.         g = pChild->winGravity;
  2141.         if (g != UnmapGravity)
  2142.         {
  2143.         if (!gravitate[g])
  2144.             gravitate[g] = (*pScreen->RegionCreate) (NullBox, 1);
  2145.         (*pScreen->Union) (gravitate[g],
  2146.                    gravitate[g], &pChild->borderClip);
  2147.         }
  2148.         else
  2149.         {
  2150.         UnmapWindow(pChild, TRUE);
  2151.         anyMarked = TRUE;
  2152.         }
  2153.     }
  2154.     anyMarked |= MarkOverlappedWindows(pWin, pWin);
  2155.  
  2156.     oldWinClip = NULL;
  2157.     if (pWin->bitGravity != ForgetGravity)
  2158.     {
  2159.         oldWinClip = (*pScreen->RegionCreate) (NullBox, 1);
  2160.         (*pScreen->RegionCopy) (oldWinClip, &pWin->clipList);
  2161.     }
  2162.         /*
  2163.           * if the window is changing size, borderExposed
  2164.           * can't be computed correctly without some help.
  2165.           */
  2166.         if (pWin->drawable.height > h || pWin->drawable.width > w)
  2167.         shrunk = TRUE;
  2168.  
  2169.     if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
  2170.         HasBorder (pWin))
  2171.     {
  2172.         borderVisible = (*pScreen->RegionCreate) (NullBox, 1);
  2173.         if (shrunk || newx != oldx || newy != oldy)
  2174.         (*pScreen->Subtract) (borderVisible, &pWin->borderClip,
  2175.                       &pWin->winSize);
  2176.         else
  2177.         (*pScreen->RegionCopy) (borderVisible, &pWin->borderClip);
  2178.     }
  2179.     }
  2180.     pWin->origin.x = x + bw;
  2181.     pWin->origin.y = y + bw;
  2182.     pWin->drawable.height = h;
  2183.     pWin->drawable.width = w;
  2184.  
  2185.     x = pWin->drawable.x = newx;
  2186.     y = pWin->drawable.y = newy;
  2187.  
  2188.     SetWinSize (pWin);
  2189.     SetBorderSize (pWin);
  2190.  
  2191.     dw = (int)w - (int)width;
  2192.     dh = (int)h - (int)height;
  2193.     ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
  2194.  
  2195.     /* let the hardware adjust background and border pixmaps, if any */
  2196.     (* pScreen->PositionWindow)(pWin, x, y);
  2197.  
  2198.     pFirstChange = MoveWindowInStack(pWin, pSib);
  2199.  
  2200.     if (WasViewable)
  2201.     {
  2202.     pRegion = (*pScreen->RegionCreate) (NullBox, 1);
  2203.     if (pWin->backStorage)
  2204.         (*pScreen->RegionCopy) (pRegion, &pWin->clipList);
  2205.  
  2206.     anyMarked |= MarkOverlappedWindows(pWin, pFirstChange);
  2207.  
  2208.     if (pWin->valdata)
  2209.      {
  2210.         pWin->valdata->before.shrunk = shrunk;
  2211.         pWin->valdata->before.borderVisible = borderVisible;
  2212.     }
  2213.  
  2214. #ifdef DO_SAVE_UNDERS
  2215.     if (DO_SAVE_UNDERS(pWin))
  2216.     {
  2217.         if (pWin->saveUnder)
  2218.         dosave = ChangeSaveUnder(pWin, pFirstChange);
  2219.         else
  2220.         dosave = CheckSaveUnder(pWin);
  2221.     }
  2222. #endif /* DO_SAVE_UNDERS */
  2223.  
  2224.     if (anyMarked)
  2225.         (* pScreen->ValidateTree)(pParent, pFirstChange, VTOther);
  2226.     /*
  2227.      * the entire window is trashed unless bitGravity
  2228.      * recovers portions of it
  2229.      */
  2230.     (*pScreen->RegionCopy) (&pWin->valdata->after.exposed, &pWin->clipList);
  2231.     }
  2232.  
  2233.     GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
  2234.  
  2235.     if (pWin->backStorage &&
  2236.     ((pWin->backingStore == Always) || WasViewable))
  2237.     {
  2238.     if (!WasViewable)
  2239.         pRegion = &pWin->clipList; /* a convenient empty region */
  2240.     if (pWin->bitGravity == ForgetGravity)
  2241.         bsExposed = (* pScreen->TranslateBackingStore)
  2242.                 (pWin, 0, 0, NullRegion);
  2243.     else
  2244.     {
  2245.         bsExposed = (* pScreen->TranslateBackingStore)
  2246.                 (pWin, nx - x, ny - y, pRegion);
  2247.     }
  2248.     }
  2249.  
  2250.     if (WasViewable)
  2251.     {
  2252.     /*
  2253.      * add screen bits to the appropriate bucket
  2254.      */
  2255.  
  2256.     if (oldWinClip)
  2257.     {
  2258.         /*
  2259.          * clip to new clipList
  2260.          */
  2261.         (*pScreen->RegionCopy) (pRegion, oldWinClip);
  2262.         (*pScreen->TranslateRegion) (pRegion, nx - oldx, ny - oldy);
  2263.         (*pScreen->Intersect) (oldWinClip, pRegion, &pWin->clipList);
  2264.         /*
  2265.          * don't step on any gravity bits which will be copied after this
  2266.          * region.  Note -- this assumes that the regions will be copied
  2267.          * in gravity order.
  2268.          */
  2269.         for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
  2270.         {
  2271.         if (gravitate[g])
  2272.             (*pScreen->Subtract) (oldWinClip, oldWinClip, gravitate[g]);
  2273.         }
  2274.         (*pScreen->TranslateRegion) (oldWinClip, oldx - nx, oldy - ny);
  2275.         g = pWin->bitGravity;
  2276.         if (!gravitate[g])
  2277.         gravitate[g] = oldWinClip;
  2278.         else
  2279.         {
  2280.         (*pScreen->Union) (gravitate[g], gravitate[g], oldWinClip);
  2281.         (*pScreen->RegionDestroy) (oldWinClip);
  2282.         }
  2283.     }
  2284.  
  2285.     /*
  2286.      * move the bits on the screen
  2287.      */
  2288.  
  2289.     destClip = NULL;
  2290.  
  2291.     for (g = 0; g <= StaticGravity; g++)
  2292.     {
  2293.         if (!gravitate[g])
  2294.             continue;
  2295.  
  2296.         GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
  2297.  
  2298.             oldpt.x = oldx + (x - nx);
  2299.         oldpt.y = oldy + (y - ny);
  2300.  
  2301.         /* Note that gravitate[g] is *translated* by CopyWindow */
  2302.  
  2303.         /* only copy the remaining useful bits */
  2304.  
  2305.         (*pScreen->Intersect) (gravitate[g], gravitate[g], oldRegion);
  2306.  
  2307.         /* clip to not overwrite already copied areas */
  2308.  
  2309.         if (destClip) {
  2310.         (*pScreen->TranslateRegion) (destClip, oldpt.x - x, oldpt.y - y);
  2311.         (*pScreen->Subtract) (gravitate[g], gravitate[g], destClip);
  2312.         (*pScreen->TranslateRegion) (destClip, x - oldpt.x, y - oldpt.y);
  2313.         }
  2314.  
  2315.         /* and move those bits */
  2316.  
  2317.         if (oldpt.x != x || oldpt.y != y)
  2318.         (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
  2319.  
  2320.         /* remove any overwritten bits from the remaining useful bits */
  2321.  
  2322.         (*pScreen->Subtract) (oldRegion, oldRegion, gravitate[g]);
  2323.  
  2324.         /*
  2325.          * recompute exposed regions of child windows
  2326.          */
  2327.     
  2328.         for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
  2329.         {
  2330.         if (pChild->winGravity != g)
  2331.             continue;
  2332.         (*pScreen->Intersect) (pRegion,
  2333.                        &pChild->borderClip, gravitate[g]);
  2334.         TraverseTree (pChild, RecomputeExposures, (pointer)pRegion);
  2335.         }
  2336.  
  2337.         /*
  2338.          * remove the successfully copied regions of the
  2339.          * window from its exposed region
  2340.          */
  2341.  
  2342.         if (g == pWin->bitGravity)
  2343.         (*pScreen->Subtract)(&pWin->valdata->after.exposed,
  2344.                      &pWin->valdata->after.exposed, gravitate[g]);
  2345.         if (!destClip)
  2346.             destClip = gravitate[g];
  2347.         else
  2348.         {
  2349.         (*pScreen->Union) (destClip, destClip, gravitate[g]);
  2350.         (*pScreen->RegionDestroy) (gravitate[g]);
  2351.         }
  2352.     }
  2353.  
  2354.     (*pScreen->RegionDestroy) (oldRegion);
  2355.     (*pScreen->RegionDestroy) (pRegion);
  2356.     if (destClip)
  2357.         (*pScreen->RegionDestroy) (destClip);
  2358.     if (bsExposed)
  2359.     {
  2360.         RegionPtr    valExposed = NullRegion;
  2361.  
  2362.         if (pWin->valdata)
  2363.         valExposed = &pWin->valdata->after.exposed;
  2364.         (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
  2365.         if (valExposed)
  2366.         (*pScreen->RegionEmpty) (valExposed);
  2367.         (*pScreen->RegionDestroy) (bsExposed);
  2368.     }
  2369.     if (anyMarked)
  2370.         HandleExposures(pParent);
  2371. #ifdef DO_SAVE_UNDERS
  2372.     if (dosave)
  2373.         DoChangeSaveUnder(pParent, pFirstChange);
  2374. #endif /* DO_SAVE_UNDERS */
  2375.     }
  2376.     else if (bsExposed)
  2377.     {
  2378.     (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
  2379.     (*pScreen->RegionDestroy) (bsExposed);
  2380.     }
  2381.     if (pWin->realized)
  2382.     WindowsRestructured ();
  2383. }
  2384.  
  2385. /* Keeps the same inside(!) origin */
  2386.  
  2387. static void
  2388. ChangeBorderWidth(pWin, width)
  2389.     register WindowPtr pWin;
  2390.     unsigned short width;
  2391. {
  2392.     WindowPtr pParent;
  2393.     int oldwidth;
  2394.     Bool anyMarked;
  2395.     register ScreenPtr pScreen;
  2396.     Bool WasViewable = (Bool)(pWin->viewable);
  2397.     Bool HadBorder;
  2398. #ifdef DO_SAVE_UNDERS
  2399.     Bool    dosave = FALSE;
  2400. #endif
  2401.  
  2402.     oldwidth = wBorderWidth (pWin);
  2403.     if (oldwidth == width)
  2404.         return;
  2405.     HadBorder = HasBorder(pWin);
  2406.     pScreen = pWin->drawable.pScreen;
  2407.     pParent = pWin->parent;
  2408.     if (WasViewable && width < oldwidth)
  2409.     anyMarked = MarkOverlappedWindows(pWin, pWin);
  2410.  
  2411.     pWin->borderWidth = width;
  2412.     SetBorderSize (pWin);
  2413.  
  2414.     if (WasViewable)
  2415.     {
  2416.         if (width > oldwidth)
  2417.     {
  2418.         anyMarked = MarkOverlappedWindows(pWin, pWin);
  2419.             /*
  2420.               * save the old border visible region to correctly compute
  2421.               * borderExposed.
  2422.               */
  2423.         if (pWin->valdata && HadBorder)
  2424.         {
  2425.             RegionPtr   borderVisible;
  2426.             borderVisible = (*pScreen->RegionCreate) (NULL, 1);
  2427.             (*pScreen->Subtract) (borderVisible,
  2428.                       &pWin->borderClip, &pWin->winSize);
  2429.             pWin->valdata->before.borderVisible = borderVisible;
  2430.         }
  2431.     }
  2432. #ifdef DO_SAVE_UNDERS
  2433.     if (DO_SAVE_UNDERS(pWin))
  2434.     {
  2435.         if (pWin->saveUnder)
  2436.         dosave = ChangeSaveUnder(pWin, pWin->nextSib);
  2437.         else
  2438.         dosave = CheckSaveUnder(pWin);
  2439.     }
  2440. #endif /* DO_SAVE_UNDERS */
  2441.  
  2442.     if (anyMarked)
  2443.     {
  2444.         (* pScreen->ValidateTree)(pParent, pWin, VTOther);
  2445.         HandleExposures(pParent);
  2446.     }
  2447. #ifdef DO_SAVE_UNDERS
  2448.     if (dosave)
  2449.         DoChangeSaveUnder(pParent, pWin->nextSib);
  2450. #endif /* DO_SAVE_UNDERS */
  2451.     }
  2452.     if (pWin->realized)
  2453.     WindowsRestructured ();
  2454. }
  2455.  
  2456.  
  2457. #define GET_INT16(m, f) \
  2458.       if (m & mask) \
  2459.           { \
  2460.              f = (INT16) *pVlist;\
  2461.          pVlist++; \
  2462.          }
  2463. #define GET_CARD16(m, f) \
  2464.      if (m & mask) \
  2465.          { \
  2466.             f = (CARD16) *pVlist;\
  2467.          pVlist++;\
  2468.          }
  2469.  
  2470. #define GET_CARD8(m, f) \
  2471.      if (m & mask) \
  2472.          { \
  2473.             f = (CARD8) *pVlist;\
  2474.          pVlist++;\
  2475.          }
  2476.  
  2477. #define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
  2478.  
  2479. #define IllegalInputOnlyConfigureMask (CWBorderWidth)
  2480.  
  2481. /*
  2482.  * IsSiblingAboveMe
  2483.  *     returns Above if pSib above pMe in stack or Below otherwise 
  2484.  */
  2485.  
  2486. static int
  2487. IsSiblingAboveMe(pMe, pSib)
  2488.     register WindowPtr pMe, pSib;
  2489. {
  2490.     register WindowPtr pWin;
  2491.  
  2492.     pWin = pMe->parent->firstChild;
  2493.     while (pWin)
  2494.     {
  2495.         if (pWin == pSib)
  2496.             return(Above);
  2497.         else if (pWin == pMe)
  2498.             return(Below);
  2499.         pWin = pWin->nextSib;
  2500.     }
  2501.     return(Below);
  2502. }
  2503.  
  2504. static BoxPtr
  2505. WindowExtents(pWin, pBox)
  2506.     register WindowPtr pWin;
  2507.     register BoxPtr pBox;
  2508. {
  2509.     pBox->x1 = pWin->origin.x - wBorderWidth (pWin);
  2510.     pBox->y1 = pWin->origin.y - wBorderWidth (pWin);
  2511.     pBox->x2 = pWin->origin.x + (int)pWin->drawable.width
  2512.            + wBorderWidth (pWin);
  2513.     pBox->y2 = pWin->origin.y + (int)pWin->drawable.height
  2514.            + wBorderWidth (pWin);
  2515.     return(pBox);
  2516. }
  2517.  
  2518. #ifdef SHAPE
  2519. #define IS_SHAPED(pWin)    (wBoundingShape (pWin) != (RegionPtr) NULL)
  2520.  
  2521. static RegionPtr
  2522. MakeBoundingRegion (pWin, pBox)
  2523.     register WindowPtr    pWin;
  2524.     BoxPtr    pBox;
  2525. {
  2526.     RegionPtr    pRgn;
  2527.     register ScreenPtr pScreen = pWin->drawable.pScreen;
  2528.  
  2529.     pRgn = (*pScreen->RegionCreate) (pBox, 1);
  2530.     if (wBoundingShape (pWin)) {
  2531.         (*pScreen->TranslateRegion) (pRgn, -pWin->origin.x,
  2532.                               -pWin->origin.y);
  2533.         (*pScreen->Intersect) (pRgn, pRgn, wBoundingShape (pWin));
  2534.         (*pScreen->TranslateRegion) (pRgn, pWin->origin.x,
  2535.                               pWin->origin.y);
  2536.     }
  2537.     return pRgn;
  2538. }
  2539.  
  2540. static Bool
  2541. ShapeOverlap (pWin, pWinBox, pSib, pSibBox)
  2542.     WindowPtr    pWin, pSib;
  2543.     BoxPtr    pWinBox, pSibBox;
  2544. {
  2545.     RegionPtr    pWinRgn, pSibRgn;
  2546.     register ScreenPtr    pScreen;
  2547.     Bool    ret;
  2548.  
  2549.     if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
  2550.     return TRUE;
  2551.     pScreen = pWin->drawable.pScreen;
  2552.     pWinRgn = MakeBoundingRegion (pWin, pWinBox);
  2553.     pSibRgn = MakeBoundingRegion (pSib, pSibBox);
  2554.     (*pScreen->Intersect) (pWinRgn, pWinRgn, pSibRgn);
  2555.     ret = (*pScreen->RegionNotEmpty) (pWinRgn);
  2556.     (*pScreen->RegionDestroy) (pWinRgn);
  2557.     (*pScreen->RegionDestroy) (pSibRgn);
  2558.     return ret;
  2559. }
  2560. #endif
  2561.  
  2562. static Bool
  2563. AnyWindowOverlapsMe(pWin, pHead, box)
  2564.     WindowPtr pWin, pHead;
  2565.     register BoxPtr box;
  2566. {
  2567.     register WindowPtr pSib;
  2568.     BoxRec sboxrec;
  2569.     register BoxPtr sbox;
  2570.  
  2571.     for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
  2572.     {
  2573.     if (pSib->mapped)
  2574.     {
  2575.         sbox = WindowExtents(pSib, &sboxrec);
  2576.         if (BOXES_OVERLAP(sbox, box)
  2577. #ifdef SHAPE
  2578.         && ShapeOverlap (pWin, box, pSib, sbox)
  2579. #endif
  2580.         )
  2581.         return(TRUE);
  2582.     }
  2583.     }
  2584.     return(FALSE);
  2585. }
  2586.  
  2587. static Bool
  2588. IOverlapAnyWindow(pWin, box)
  2589.     WindowPtr pWin;
  2590.     register BoxPtr box;
  2591. {
  2592.     register WindowPtr pSib;
  2593.     BoxRec sboxrec;
  2594.     register BoxPtr sbox;
  2595.  
  2596.     for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
  2597.     {
  2598.     if (pSib->mapped)
  2599.     {
  2600.         sbox = WindowExtents(pSib, &sboxrec);
  2601.         if (BOXES_OVERLAP(sbox, box)
  2602. #ifdef SHAPE
  2603.         && ShapeOverlap (pWin, box, pSib, sbox)
  2604. #endif
  2605.         )
  2606.         return(TRUE);
  2607.     }
  2608.     }
  2609.     return(FALSE);
  2610. }
  2611.  
  2612. /*
  2613.  *   WhereDoIGoInTheStack() 
  2614.  *        Given pWin and pSib and the relationshipe smode, return
  2615.  *        the window that pWin should go ABOVE.
  2616.  *        If a pSib is specified:
  2617.  *            Above:  pWin is placed just above pSib
  2618.  *            Below:  pWin is placed just below pSib
  2619.  *            TopIf:  if pSib occludes pWin, then pWin is placed
  2620.  *                    at the top of the stack
  2621.  *            BottomIf:  if pWin occludes pSib, then pWin is 
  2622.  *                       placed at the bottom of the stack
  2623.  *            Opposite: if pSib occludes pWin, then pWin is placed at the
  2624.  *                      top of the stack, else if pWin occludes pSib, then
  2625.  *                      pWin is placed at the bottom of the stack
  2626.  *
  2627.  *        If pSib is NULL:
  2628.  *            Above:  pWin is placed at the top of the stack
  2629.  *            Below:  pWin is placed at the bottom of the stack
  2630.  *            TopIf:  if any sibling occludes pWin, then pWin is placed at
  2631.  *                    the top of the stack
  2632.  *            BottomIf: if pWin occludes any sibline, then pWin is placed at
  2633.  *                      the bottom of the stack
  2634.  *            Opposite: if any sibling occludes pWin, then pWin is placed at
  2635.  *                      the top of the stack, else if pWin occludes any
  2636.  *                      sibling, then pWin is placed at the bottom of the stack
  2637.  *
  2638.  */
  2639.  
  2640. static WindowPtr
  2641. WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode)
  2642.     register WindowPtr pWin, pSib;
  2643.     short x, y;
  2644.     unsigned short w, h;
  2645.     int smode;
  2646. {
  2647.     BoxRec box;
  2648.     register ScreenPtr pScreen;
  2649.     WindowPtr pHead, pFirst;
  2650.  
  2651.     if ((pWin == pWin->parent->firstChild) &&
  2652.     (pWin == pWin->parent->lastChild))
  2653.         return((WindowPtr ) NULL);
  2654.     pHead = RealChildHead(pWin->parent);
  2655.     pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
  2656.     pScreen = pWin->drawable.pScreen;
  2657.     box.x1 = x;
  2658.     box.y1 = y;
  2659.     box.x2 = x + (int)w;
  2660.     box.y2 = y + (int)h;
  2661.     switch (smode)
  2662.     {
  2663.       case Above:
  2664.         if (pSib)
  2665.            return(pSib);
  2666.         else if (pWin == pFirst)
  2667.             return(pWin->nextSib);
  2668.         else
  2669.             return(pFirst);
  2670.       case Below:
  2671.         if (pSib)
  2672.         if (pSib->nextSib != pWin)
  2673.             return(pSib->nextSib);
  2674.         else
  2675.             return(pWin->nextSib);
  2676.         else
  2677.             return NullWindow;
  2678.       case TopIf:
  2679.         if (pSib)
  2680.     {
  2681.             if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
  2682.                 ((* pScreen->RectIn)(&pSib->borderSize, &box) != rgnOUT))
  2683.                 return(pFirst);
  2684.             else
  2685.                 return(pWin->nextSib);
  2686.     }
  2687.         else if (AnyWindowOverlapsMe(pWin, pHead, &box))
  2688.             return(pFirst);
  2689.         else
  2690.             return(pWin->nextSib);
  2691.       case BottomIf:
  2692.         if (pSib)
  2693.     {
  2694.             if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
  2695.                 ((* pScreen->RectIn)(&pSib->borderSize, &box) != rgnOUT))
  2696.                 return NullWindow;
  2697.             else
  2698.                 return(pWin->nextSib);
  2699.     }
  2700.         else if (IOverlapAnyWindow(pWin, &box))
  2701.             return NullWindow;
  2702.         else
  2703.             return(pWin->nextSib);
  2704.       case Opposite:
  2705.         if (pSib)
  2706.     {
  2707.         if ((* pScreen->RectIn)(&pSib->borderSize, &box) != rgnOUT)
  2708.             {
  2709.                 if (IsSiblingAboveMe(pWin, pSib) == Above)
  2710.                     return(pFirst);
  2711.                 else
  2712.                     return NullWindow;
  2713.             }
  2714.             else
  2715.                 return(pWin->nextSib);
  2716.     }
  2717.         else if (AnyWindowOverlapsMe(pWin, pHead, &box))
  2718.     {
  2719.         /* If I'm occluded, I can't possibly be the first child
  2720.              * if (pWin == pWin->parent->firstChild)
  2721.              *    return pWin->nextSib;
  2722.          */
  2723.             return(pFirst);
  2724.     }
  2725.         else if (IOverlapAnyWindow(pWin, &box))
  2726.             return NullWindow;
  2727.         else
  2728.             return pWin->nextSib;
  2729.       default:
  2730.       {
  2731.         ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
  2732.         return pWin->nextSib;
  2733.       }
  2734.     }
  2735. }
  2736.  
  2737. static void
  2738. ReflectStackChange(pWin, pSib, kind)
  2739.     register WindowPtr pWin, pSib;
  2740.     VTKind  kind;
  2741. {
  2742. /* Note that pSib might be NULL */
  2743.  
  2744.     Bool WasViewable = (Bool)pWin->viewable;
  2745.     WindowPtr pParent;
  2746.     Bool anyMarked;
  2747.     WindowPtr pFirstChange;
  2748. #ifdef DO_SAVE_UNDERS
  2749.     Bool    dosave = FALSE;
  2750. #endif
  2751.  
  2752.     /* if this is a root window, can't be restacked */
  2753.     if (!(pParent = pWin->parent))
  2754.         return ;
  2755.  
  2756.     pFirstChange = MoveWindowInStack(pWin, pSib);
  2757.  
  2758.     if (WasViewable)
  2759.     {
  2760.     anyMarked = MarkOverlappedWindows(pWin, pFirstChange);
  2761. #ifdef DO_SAVE_UNDERS
  2762.     if (DO_SAVE_UNDERS(pWin))
  2763.     {
  2764.         if (pWin->saveUnder)
  2765.         dosave = ChangeSaveUnder(pWin, pFirstChange);
  2766.         else
  2767.         dosave = CheckSaveUnder(pWin);
  2768.     }
  2769. #endif /* DO_SAVE_UNDERS */
  2770.     if (anyMarked)
  2771.     {
  2772.         (* pWin->drawable.pScreen->ValidateTree)(pParent, pFirstChange,
  2773.                              kind);
  2774.         HandleExposures(pParent);
  2775.     }
  2776. #ifdef DO_SAVE_UNDERS
  2777.     if (dosave)
  2778.         DoChangeSaveUnder(pParent, pFirstChange);
  2779. #endif /* DO_SAVE_UNDERS */
  2780.     }
  2781.     if (pWin->realized)
  2782.     WindowsRestructured ();
  2783. }
  2784.  
  2785. /*****
  2786.  * ConfigureWindow
  2787.  *****/
  2788.  
  2789.  
  2790. int
  2791. ConfigureWindow(pWin, mask, vlist, client)
  2792.     register WindowPtr pWin;
  2793.     register Mask mask;
  2794.     XID *vlist;
  2795.     ClientPtr client;
  2796. {
  2797. #define RESTACK_WIN    0
  2798. #define MOVE_WIN       1
  2799. #define RESIZE_WIN     2
  2800. #define REBORDER_WIN   3
  2801.     register WindowPtr pSib = NullWindow;
  2802.     register WindowPtr pParent = pWin->parent;
  2803.     Window sibwid;
  2804.     Mask index, tmask;
  2805.     register XID *pVlist;
  2806.     short x,   y, beforeX, beforeY;
  2807.     unsigned short w = pWin->drawable.width,
  2808.                    h = pWin->drawable.height,
  2809.                bw = pWin->borderWidth;
  2810.     int action,
  2811.         smode = Above;
  2812.     xEvent event;
  2813.  
  2814.     if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
  2815.         return(BadMatch);
  2816.  
  2817.     if ((mask & CWSibling) && !(mask & CWStackMode))
  2818.         return(BadMatch);
  2819.  
  2820.     pVlist = vlist;
  2821.  
  2822.     if (pParent)
  2823.     {
  2824.         x = pWin->drawable.x - pParent->drawable.x - (int)bw;
  2825.         y = pWin->drawable.y - pParent->drawable.y - (int)bw;
  2826.     }
  2827.     else
  2828.     {
  2829.         x = pWin->drawable.x;
  2830.         y = pWin->drawable.y;
  2831.     }
  2832.     beforeX = x;
  2833.     beforeY = y;
  2834.     action = RESTACK_WIN;    
  2835.     if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
  2836.     {
  2837.     GET_INT16(CWX, x);
  2838.      GET_INT16(CWY, y);
  2839.     action = MOVE_WIN;
  2840.     }
  2841.     /* or should be resized */
  2842.     else if (mask & (CWX |  CWY | CWWidth | CWHeight))
  2843.     {
  2844.     GET_INT16(CWX, x);
  2845.     GET_INT16(CWY, y);
  2846.     GET_CARD16(CWWidth, w);
  2847.     GET_CARD16 (CWHeight, h);
  2848.     if (!w || !h)
  2849.     {
  2850.         client->errorValue = 0;
  2851.             return BadValue;
  2852.     }
  2853.         action = RESIZE_WIN;
  2854.     }
  2855.     tmask = mask & ~ChangeMask;
  2856.     while (tmask)
  2857.     {
  2858.     index = (Mask)lowbit (tmask);
  2859.     tmask &= ~index;
  2860.     switch (index)
  2861.         {
  2862.           case CWBorderWidth:
  2863.         GET_CARD16(CWBorderWidth, bw);
  2864.         break;
  2865.           case CWSibling:
  2866.         sibwid = (Window ) *pVlist;
  2867.         pVlist++;
  2868.             pSib = (WindowPtr )LookupIDByType(sibwid, RT_WINDOW);
  2869.             if (!pSib)
  2870.         {
  2871.         client->errorValue = sibwid;
  2872.                 return(BadWindow);
  2873.         }
  2874.             if (pSib->parent != pParent)
  2875.         return(BadMatch);
  2876.         if (pSib == pWin)
  2877.             return(BadMatch);
  2878.         break;
  2879.           case CWStackMode:
  2880.         GET_CARD8(CWStackMode, smode);
  2881.         if ((smode != TopIf) && (smode != BottomIf) &&
  2882.          (smode != Opposite) && (smode != Above) && (smode != Below))
  2883.                    return(BadMatch);
  2884.         break;
  2885.       default:
  2886.         client->errorValue = mask;
  2887.         return(BadValue);
  2888.     }
  2889.     }
  2890.     /* root really can't be reconfigured, so just return */
  2891.     if (!pParent)
  2892.     return Success;
  2893.  
  2894.         /* Figure out if the window should be moved.  Doesnt
  2895.            make the changes to the window if event sent */
  2896.  
  2897.     if (mask & CWStackMode)
  2898.         pSib = WhereDoIGoInTheStack(pWin, pSib, x, y,
  2899.                     w + (bw << 1), h + (bw << 1), smode);
  2900.     else
  2901.         pSib = pWin->nextSib;
  2902.  
  2903.     if ((!pWin->overrideRedirect) && RedirectSend(pParent))
  2904.     {
  2905.     event.u.u.type = ConfigureRequest;
  2906.     event.u.configureRequest.window = pWin->drawable.id;
  2907.     event.u.configureRequest.parent = pParent->drawable.id;
  2908.         if (mask & CWSibling)
  2909.        event.u.configureRequest.sibling = sibwid;
  2910.         else
  2911.                event.u.configureRequest.sibling = None;
  2912.         if (mask & CWStackMode)
  2913.        event.u.u.detail = smode;
  2914.         else
  2915.                event.u.u.detail = Above;
  2916.     event.u.configureRequest.x = x;
  2917.     event.u.configureRequest.y = y;
  2918.     event.u.configureRequest.width = w;
  2919.     event.u.configureRequest.height = h;
  2920.     event.u.configureRequest.borderWidth = bw;
  2921.     event.u.configureRequest.valueMask = mask;
  2922.     if (MaybeDeliverEventsToClient(pParent, &event, 1,
  2923.             SubstructureRedirectMask, client) == 1)
  2924.             return(Success);
  2925.     }
  2926.     if (action == RESIZE_WIN)
  2927.     {
  2928.         Bool size_change = (w != pWin->drawable.width)
  2929.                         || (h != pWin->drawable.height);
  2930.     if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
  2931.     {
  2932.         xEvent eventT;
  2933.             eventT.u.u.type = ResizeRequest;
  2934.             eventT.u.resizeRequest.window = pWin->drawable.id;
  2935.         eventT.u.resizeRequest.width = w;
  2936.         eventT.u.resizeRequest.height = h;
  2937.         if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
  2938.                        ResizeRedirectMask, client) == 1)
  2939.         {
  2940.                 /* if event is delivered, leave the actual size alone. */
  2941.             w = pWin->drawable.width;
  2942.             h = pWin->drawable.height;
  2943.                 size_change = FALSE;
  2944.         }
  2945.     }
  2946.         if (!size_change)
  2947.     {
  2948.         if (mask & (CWX | CWY))
  2949.                 action = MOVE_WIN;
  2950.         else if (mask & (CWStackMode | CWBorderWidth))
  2951.             action = RESTACK_WIN;
  2952.             else   /* really nothing to do */
  2953.                 return(Success) ;
  2954.     }
  2955.     }
  2956.  
  2957.     if (action == RESIZE_WIN)
  2958.             /* we've already checked whether there's really a size change */
  2959.             goto ActuallyDoSomething;
  2960.     if ((mask & CWX) && (x != beforeX))
  2961.             goto ActuallyDoSomething;
  2962.     if ((mask & CWY) && (y != beforeY))
  2963.             goto ActuallyDoSomething;
  2964.     if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
  2965.             goto ActuallyDoSomething;
  2966.     if (mask & CWStackMode)
  2967.     {
  2968.         if (pWin->nextSib != pSib)
  2969.             goto ActuallyDoSomething;
  2970.     }
  2971.     return(Success);
  2972.  
  2973. ActuallyDoSomething:
  2974.     if (SubStrSend(pWin, pParent))
  2975.     {
  2976.     event.u.u.type = ConfigureNotify;
  2977.     event.u.configureNotify.window = pWin->drawable.id;
  2978.     if (pSib)
  2979.         event.u.configureNotify.aboveSibling = pSib->drawable.id;
  2980.     else
  2981.         event.u.configureNotify.aboveSibling = None;
  2982.     event.u.configureNotify.x = x;
  2983.     event.u.configureNotify.y = y;
  2984.     event.u.configureNotify.width = w;
  2985.     event.u.configureNotify.height = h;
  2986.     event.u.configureNotify.borderWidth = bw;
  2987.     event.u.configureNotify.override = pWin->overrideRedirect;
  2988.     DeliverEvents(pWin, &event, 1, NullWindow);
  2989.     }
  2990.     if (mask & CWBorderWidth)
  2991.     {
  2992.     if (action == RESTACK_WIN)
  2993.     {
  2994.         action = MOVE_WIN;
  2995.         pWin->borderWidth = bw;
  2996.     }
  2997.     else if ((action == MOVE_WIN) &&
  2998.          ((int)bw == (x - beforeX)) && ((int)bw == (y - beforeY)))
  2999.     {
  3000.         action = REBORDER_WIN;
  3001.             ChangeBorderWidth(pWin, bw);
  3002.     }
  3003.         else
  3004.         pWin->borderWidth = bw;
  3005.     }
  3006.     if (action == MOVE_WIN)
  3007.         MoveWindow(pWin, x, y, pSib,
  3008.            (mask & CWBorderWidth) ? VTOther : VTMove);
  3009.     else if (action == RESIZE_WIN)
  3010.         SlideAndSizeWindow(pWin, x, y, w, h, pSib);
  3011.     else if (mask & CWStackMode)
  3012.         ReflectStackChange(pWin, pSib, VTOther);
  3013.  
  3014.     if (action != RESTACK_WIN)
  3015.     CheckCursorConfinement(pWin);
  3016.  
  3017.     return(Success);
  3018. #undef RESTACK_WIN
  3019. #undef MOVE_WIN
  3020. #undef RESIZE_WIN
  3021. #undef REBORDER_WIN
  3022. }
  3023.  
  3024. #ifdef SHAPE
  3025. /******
  3026.  *
  3027.  * SetShape
  3028.  *    The border/window shape has changed.  Recompute winSize/borderSize
  3029.  *    and send appropriate exposure events
  3030.  */
  3031.  
  3032. SetShape(pWin)
  3033.     register WindowPtr    pWin;
  3034. {
  3035.     Bool    WasViewable = (Bool)(pWin->viewable);
  3036.     register ScreenPtr pScreen = pWin->drawable.pScreen;
  3037.     Bool    anyMarked;
  3038.     WindowPtr    pParent = pWin->parent;
  3039. #ifdef DO_SAVE_UNDERS
  3040.     Bool    dosave = FALSE;
  3041. #endif
  3042.  
  3043.     if (WasViewable)
  3044.     {
  3045.     anyMarked = MarkOverlappedWindows(pWin, pWin);
  3046.     if (pWin->valdata && HasBorder(pWin))
  3047.     {
  3048.         RegionPtr    borderVisible;
  3049.  
  3050.         borderVisible = (*pScreen->RegionCreate) (NullBox, 1);
  3051.         (*pScreen->Subtract) (borderVisible,
  3052.                   &pWin->borderClip, &pWin->winSize);
  3053.         pWin->valdata->before.borderVisible = borderVisible;
  3054.         pWin->valdata->before.shrunk = TRUE;
  3055.     }
  3056.     }
  3057.  
  3058.     SetWinSize (pWin);
  3059.     SetBorderSize (pWin);
  3060.  
  3061.     ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
  3062.  
  3063.     if (WasViewable)
  3064.     {
  3065.     anyMarked |= MarkOverlappedWindows(pWin, pWin);
  3066.  
  3067. #ifdef DO_SAVE_UNDERS
  3068.     if (DO_SAVE_UNDERS(pWin))
  3069.     {
  3070.         if (pWin->saveUnder)
  3071.         dosave = ChangeSaveUnder(pWin, pWin);
  3072.         else
  3073.         dosave = CheckSaveUnder(pWin);
  3074.     }
  3075. #endif /* DO_SAVE_UNDERS */
  3076.  
  3077.     if (anyMarked)
  3078.     {
  3079.         (* pScreen->ValidateTree)(pParent, NullWindow, VTOther);
  3080.         HandleExposures(pParent);
  3081.     }
  3082. #ifdef DO_SAVE_UNDERS
  3083.     if (dosave)
  3084.         DoChangeSaveUnder(pParent, pWin);
  3085. #endif /* DO_SAVE_UNDERS */
  3086.     }
  3087.     if (pWin->realized)
  3088.     WindowsRestructured ();
  3089.     CheckCursorConfinement(pWin);
  3090. }
  3091. #endif
  3092.  
  3093. /******
  3094.  *
  3095.  * CirculateWindow
  3096.  *    For RaiseLowest, raises the lowest mapped child (if any) that is
  3097.  *    obscured by another child to the top of the stack.  For LowerHighest,
  3098.  *    lowers the highest mapped child (if any) that is obscuring another
  3099.  *    child to the bottom of the stack.  Exposure processing is performed 
  3100.  *
  3101.  ******/
  3102.  
  3103. int
  3104. CirculateWindow(pParent, direction, client)
  3105.     WindowPtr pParent;
  3106.     int direction;
  3107.     ClientPtr client;
  3108. {
  3109.     register WindowPtr pWin, pHead, pFirst;
  3110.     xEvent event;
  3111.     BoxRec box;
  3112.  
  3113.     pHead = RealChildHead(pParent);
  3114.     pFirst = pHead ? pHead->nextSib : pParent->firstChild;
  3115.     if (direction == RaiseLowest)
  3116.     {
  3117.     for (pWin = pParent->lastChild;
  3118.          (pWin != pHead) &&
  3119.          !(pWin->mapped &&
  3120.            AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
  3121.          pWin = pWin->prevSib) ;
  3122.     if (pWin == pHead)
  3123.         return Success;
  3124.     }
  3125.     else
  3126.     {
  3127.     for (pWin = pFirst;
  3128.          pWin &&
  3129.          !(pWin->mapped &&
  3130.            IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
  3131.          pWin = pWin->nextSib) ;
  3132.     if (!pWin)
  3133.         return Success;
  3134.     }
  3135.  
  3136.     event.u.circulate.window = pWin->drawable.id;
  3137.     event.u.circulate.parent = pParent->drawable.id;
  3138.     event.u.circulate.event = pParent->drawable.id;
  3139.     if (direction == RaiseLowest)
  3140.     event.u.circulate.place = PlaceOnTop;
  3141.     else
  3142.         event.u.circulate.place = PlaceOnBottom;
  3143.  
  3144.     if (RedirectSend(pParent))
  3145.     {
  3146.     event.u.u.type = CirculateRequest;
  3147.     if (MaybeDeliverEventsToClient(pParent, &event, 1,
  3148.             SubstructureRedirectMask, client) == 1)
  3149.             return(Success);
  3150.     }
  3151.  
  3152.     event.u.u.type = CirculateNotify;
  3153.     DeliverEvents(pWin, &event, 1, NullWindow);
  3154.     ReflectStackChange(pWin,
  3155.                (direction == RaiseLowest) ? pFirst : NullWindow,
  3156.                VTStack);
  3157.  
  3158.     return(Success);
  3159. }
  3160.  
  3161. static int
  3162. CompareWIDs(pWin, wid)
  3163.     WindowPtr pWin;
  3164.     Window *wid;
  3165. {
  3166.     if (pWin->drawable.id == *wid)
  3167.        return(WT_STOPWALKING);
  3168.     else
  3169.        return(WT_WALKCHILDREN);
  3170. }
  3171.  
  3172. /*****
  3173.  *  ReparentWindow
  3174.  *****/
  3175.  
  3176. int
  3177. ReparentWindow(pWin, pParent, x, y, client)
  3178.     register WindowPtr pWin, pParent;
  3179.     short x,y;
  3180.     ClientPtr client;
  3181. {
  3182.     WindowPtr pPrev;
  3183.     Bool WasMapped = (Bool)(pWin->mapped);
  3184.     xEvent event;
  3185.     int bw = wBorderWidth (pWin);
  3186.     register ScreenPtr pScreen;
  3187.  
  3188.     pScreen = pWin->drawable.pScreen;
  3189.     if (pScreen != pParent->drawable.pScreen)
  3190.         return(BadMatch);
  3191.     if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
  3192.         return(BadMatch);        
  3193.     if (!MakeWindowOptional(pWin))
  3194.     return(BadAlloc);
  3195.  
  3196.     if (WasMapped)
  3197.        UnmapWindow(pWin, FALSE);
  3198.  
  3199.     event.u.u.type = ReparentNotify;
  3200.     event.u.reparent.window = pWin->drawable.id;
  3201.     event.u.reparent.parent = pParent->drawable.id;
  3202.     event.u.reparent.x = x;
  3203.     event.u.reparent.y = y;
  3204.     event.u.reparent.override = pWin->overrideRedirect;
  3205.     DeliverEvents(pWin, &event, 1, pParent);
  3206.  
  3207.     /* take out of sibling chain */
  3208.  
  3209.     pPrev = pWin->parent;
  3210.     if (pPrev->firstChild == pWin)
  3211.         pPrev->firstChild = pWin->nextSib;
  3212.     if (pPrev->lastChild == pWin)
  3213.         pPrev->lastChild = pWin->prevSib;
  3214.  
  3215.     if (pWin->nextSib)
  3216.         pWin->nextSib->prevSib = pWin->prevSib;
  3217.     if (pWin->prevSib)
  3218.         pWin->prevSib->nextSib = pWin->nextSib;
  3219.  
  3220.     /* insert at begining of pParent */
  3221.     pWin->parent = pParent;
  3222.     pPrev = RealChildHead(pParent);
  3223.     if (pPrev)
  3224.     {
  3225.     pWin->nextSib = pPrev->nextSib;
  3226.         if (pPrev->nextSib)
  3227.             pPrev->nextSib->prevSib = pWin;
  3228.     else
  3229.         pParent->lastChild = pWin;
  3230.         pPrev->nextSib = pWin;
  3231.     pWin->prevSib = pPrev;
  3232.     }
  3233.     else
  3234.     {
  3235.         pWin->nextSib = pParent->firstChild;
  3236.     pWin->prevSib = NullWindow;
  3237.         if (pParent->firstChild)
  3238.         pParent->firstChild->prevSib = pWin;
  3239.         else
  3240.             pParent->lastChild = pWin;
  3241.     pParent->firstChild = pWin;
  3242.     }
  3243.  
  3244.     pWin->origin.x = x + bw;
  3245.     pWin->origin.y = y + bw;
  3246.     pWin->drawable.x = x + bw + pParent->drawable.x;
  3247.     pWin->drawable.y = y + bw + pParent->drawable.y;
  3248.  
  3249.     /* clip to parent */
  3250.     SetWinSize (pWin);
  3251.     SetBorderSize (pWin);
  3252.  
  3253.     (* pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
  3254.     ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
  3255.  
  3256.     CheckWindowOptionalNeed(pWin);
  3257.  
  3258.     if (WasMapped)
  3259.         MapWindow(pWin, client);
  3260.     RecalculateDeliverableEvents(pParent);
  3261.     return(Success);
  3262. }
  3263.  
  3264. static void
  3265. MarkWindow(pWin)
  3266.     register WindowPtr pWin;
  3267. {
  3268.     register ValidatePtr val;
  3269.     extern Bool Must_have_memory;
  3270.  
  3271.     if (pWin->valdata)
  3272.     return;
  3273.     Must_have_memory = TRUE; /* XXX */
  3274.     val = (ValidatePtr)xalloc(sizeof(ValidateRec));
  3275.     Must_have_memory = FALSE; /* XXX */
  3276.     val->before.oldAbsCorner.x = pWin->drawable.x;
  3277.     val->before.oldAbsCorner.y = pWin->drawable.y;
  3278.     val->before.borderVisible = NullRegion;
  3279.     val->before.shrunk = FALSE;
  3280.     pWin->valdata = val;
  3281. }
  3282.  
  3283. static Bool
  3284. MarkOverlappedWindows(pWin, pFirst)
  3285.     WindowPtr pWin;
  3286.     WindowPtr pFirst;
  3287. {
  3288.     register BoxPtr box;
  3289.     register WindowPtr pChild, pLast;
  3290.     int (* RectIn)();
  3291.     Bool anyMarked = FALSE;
  3292.  
  3293.     if (pWin == pFirst)
  3294.     {
  3295.     /* Blindly mark pWin and all of it's inferiors.  This is a slight
  3296.      * overkill if there are mapped windows that outside pWin's border,
  3297.      * but it's better than wasting time on RectIn checks.
  3298.      */
  3299.     pChild = pWin;
  3300.     while (1)
  3301.     {
  3302.         if (pChild->viewable)
  3303.         {
  3304.         MarkWindow(pChild);
  3305.         if (pChild->firstChild)
  3306.         {
  3307.             pChild = pChild->firstChild;
  3308.             continue;
  3309.         }
  3310.         }
  3311.         while (!pChild->nextSib && (pChild != pWin))
  3312.         pChild = pChild->parent;
  3313.         if (pChild == pWin)
  3314.         break;
  3315.         pChild = pChild->nextSib;
  3316.     }
  3317.     anyMarked = TRUE;
  3318.     pFirst = pFirst->nextSib;
  3319.     }
  3320.     if (pChild = pFirst)
  3321.     {
  3322.     box = (* pChild->drawable.pScreen->RegionExtents)(&pWin->borderSize);
  3323.     RectIn = pChild->drawable.pScreen->RectIn;
  3324.     pLast = pChild->parent->lastChild;
  3325.     while (1)
  3326.     {
  3327.         if (pChild->viewable && (*RectIn)(&pChild->borderSize, box))
  3328.         {
  3329.         MarkWindow(pChild);
  3330.         anyMarked = TRUE;
  3331.         if (pChild->firstChild)
  3332.         {
  3333.             pChild = pChild->firstChild;
  3334.             continue;
  3335.         }
  3336.         }
  3337.         while (!pChild->nextSib && (pChild != pLast))
  3338.         pChild = pChild->parent;
  3339.         if (pChild == pLast)
  3340.         break;
  3341.         pChild = pChild->nextSib;
  3342.     }
  3343.     }
  3344.     if (anyMarked)
  3345.     MarkWindow(pWin->parent);
  3346.     return anyMarked;
  3347. }
  3348.  
  3349. static void
  3350. RealizeTree(pWin)
  3351.     WindowPtr pWin;
  3352. {
  3353.     register WindowPtr pChild;
  3354.     Bool (* Realize)();
  3355.  
  3356.     Realize = pWin->drawable.pScreen->RealizeWindow;
  3357.     pChild = pWin;
  3358.     while (1)
  3359.     {
  3360.     if (pChild->mapped)
  3361.     {
  3362.         pChild->realized = TRUE;
  3363. #ifdef DO_SAVE_UNDERS
  3364.         if (pChild->saveUnder)
  3365.         deltaSaveUndersViewable++;
  3366. #endif
  3367.         pChild->viewable = (pChild->drawable.class == InputOutput);
  3368.         (* Realize)(pChild);
  3369.         if (pChild->firstChild)
  3370.         {
  3371.         pChild = pChild->firstChild;
  3372.         continue;
  3373.         }
  3374.     }
  3375.     while (!pChild->nextSib && (pChild != pWin))
  3376.         pChild = pChild->parent;
  3377.     if (pChild == pWin)
  3378.         return;
  3379.     pChild = pChild->nextSib;
  3380.     }
  3381. }
  3382.  
  3383. /*****
  3384.  * MapWindow
  3385.  *    If some other client has selected SubStructureReDirect on the parent
  3386.  *    and override-redirect is xFalse, then a MapRequest event is generated,
  3387.  *    but the window remains unmapped.  Otherwise, the window is mapped and a
  3388.  *    MapNotify event is generated.
  3389.  *****/
  3390.  
  3391. int
  3392. MapWindow(pWin, client)
  3393.     register WindowPtr pWin;
  3394.     ClientPtr client;
  3395. {
  3396.     register ScreenPtr pScreen;
  3397.  
  3398.     register WindowPtr pParent;
  3399. #ifdef DO_SAVE_UNDERS
  3400.     Bool    dosave = FALSE;
  3401. #endif
  3402.  
  3403.     if (pWin->mapped)
  3404.         return(Success);
  3405.     pScreen = pWin->drawable.pScreen;
  3406.     if (pParent = pWin->parent)
  3407.     {
  3408.         xEvent event;
  3409.     Bool anyMarked;
  3410.  
  3411.         if ((!pWin->overrideRedirect) && RedirectSend(pParent))
  3412.     {
  3413.         event.u.u.type = MapRequest;
  3414.         event.u.mapRequest.window = pWin->drawable.id;
  3415.         event.u.mapRequest.parent = pParent->drawable.id;
  3416.  
  3417.         if (MaybeDeliverEventsToClient(pParent, &event, 1,
  3418.             SubstructureRedirectMask, client) == 1)
  3419.                 return(Success);
  3420.     }
  3421.  
  3422.     pWin->mapped = TRUE;
  3423.     if (SubStrSend(pWin, pParent))
  3424.     {
  3425.         event.u.u.type = MapNotify;
  3426.         event.u.mapNotify.window = pWin->drawable.id;
  3427.         event.u.mapNotify.override = pWin->overrideRedirect;
  3428.         DeliverEvents(pWin, &event, 1, NullWindow);
  3429.     }
  3430.  
  3431.         if (!pParent->realized)
  3432.             return(Success);
  3433.     RealizeTree(pWin);
  3434.     if (pWin->viewable)
  3435.     {
  3436.         anyMarked = MarkOverlappedWindows(pWin, pWin);
  3437. #ifdef DO_SAVE_UNDERS
  3438.         if (DO_SAVE_UNDERS(pWin))
  3439.         {
  3440.         if (pWin->saveUnder)
  3441.             dosave = ChangeSaveUnder(pWin, pWin->nextSib);
  3442.         else
  3443.             dosave = CheckSaveUnder(pWin);
  3444.         }
  3445. #endif /* DO_SAVE_UNDERS */
  3446.         if (anyMarked)
  3447.         {
  3448.         (* pScreen->ValidateTree)(pParent, pWin, VTMap);
  3449.         HandleExposures(pParent);
  3450.         }
  3451. #ifdef DO_SAVE_UNDERS
  3452.         if (dosave)
  3453.         DoChangeSaveUnder(pParent, pWin->nextSib);
  3454. #endif /* DO_SAVE_UNDERS */
  3455.     }
  3456.     WindowsRestructured ();
  3457.     }
  3458.     else
  3459.     {
  3460.     RegionRec   temp;
  3461.  
  3462.     pWin->mapped = TRUE;
  3463.         pWin->realized = TRUE;     /* for roots */
  3464.         pWin->viewable = pWin->drawable.class == InputOutput;
  3465.         /* We SHOULD check for an error value here XXX */
  3466.         (* pScreen->RealizeWindow)(pWin);
  3467.     (* pScreen->RegionInit) (&temp, NullBox, 0);
  3468.     (* pScreen->RegionCopy) (&temp, &pWin->clipList);
  3469.     (*pScreen->WindowExposures) (pWin, &temp, NullRegion);
  3470.     (* pScreen->RegionUninit) (&temp);
  3471.     }
  3472.  
  3473.     return(Success);
  3474. }
  3475.  
  3476.  
  3477. /*****
  3478.  * MapSubwindows
  3479.  *    Performs a MapWindow all unmapped children of the window, in top
  3480.  *    to bottom stacking order.
  3481.  *****/
  3482.  
  3483. MapSubwindows(pParent, client)
  3484.     register WindowPtr pParent;
  3485.     ClientPtr client;
  3486. {
  3487.     register WindowPtr    pWin;
  3488.     WindowPtr        pFirstMapped = NullWindow;
  3489. #ifdef DO_SAVE_UNDERS
  3490.     WindowPtr        pFirstSaveUndered = NullWindow;
  3491. #endif
  3492.     register ScreenPtr    pScreen;
  3493.     register Mask    parentRedirect;
  3494.     register Mask    parentNotify;
  3495.     xEvent        event;
  3496.     Bool        anyMarked;
  3497. #ifdef DO_SAVE_UNDERS
  3498.     Bool    dosave = FALSE;
  3499. #endif
  3500.  
  3501.     pScreen = pParent->drawable.pScreen;
  3502.     parentRedirect = RedirectSend(pParent);
  3503.     parentNotify = SubSend(pParent);
  3504.     anyMarked = FALSE;
  3505.     for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
  3506.     {
  3507.     if (!pWin->mapped)
  3508.     {
  3509.             if (parentRedirect && !pWin->overrideRedirect)
  3510.         {
  3511.             event.u.u.type = MapRequest;
  3512.             event.u.mapRequest.window = pWin->drawable.id;
  3513.             event.u.mapRequest.parent = pParent->drawable.id;
  3514.     
  3515.             if (MaybeDeliverEventsToClient(pParent, &event, 1,
  3516.                 SubstructureRedirectMask, client) == 1)
  3517.                     continue;
  3518.         }
  3519.     
  3520.         pWin->mapped = TRUE;
  3521.         if (parentNotify || StrSend(pWin))
  3522.         {
  3523.         event.u.u.type = MapNotify;
  3524.         event.u.mapNotify.window = pWin->drawable.id;
  3525.         event.u.mapNotify.override = pWin->overrideRedirect;
  3526.         DeliverEvents(pWin, &event, 1, NullWindow);
  3527.         }
  3528.     
  3529.         if (!pFirstMapped)
  3530.         pFirstMapped = pWin;
  3531.             if (pParent->realized)
  3532.         {
  3533.             RealizeTree(pWin);
  3534.             if (pWin->viewable)
  3535.             {
  3536.                 anyMarked |= MarkOverlappedWindows(pWin, pWin);
  3537. #ifdef DO_SAVE_UNDERS
  3538.                 if (DO_SAVE_UNDERS(pWin))
  3539.                 {
  3540.                 if (pWin->saveUnder)
  3541.                     dosave |= ChangeSaveUnder(pWin, pWin->nextSib);
  3542.                 else
  3543.                     dosave |= CheckSaveUnder(pWin);
  3544.                 if (dosave && !pFirstSaveUndered)
  3545.                 pFirstSaveUndered = pWin;
  3546.                 }
  3547. #endif /* DO_SAVE_UNDERS */
  3548.             }
  3549.         }
  3550.     }
  3551.     }
  3552.  
  3553.     if (pFirstMapped)
  3554.     {
  3555.         if (anyMarked)
  3556.         {
  3557.         (* pScreen->ValidateTree)(pParent, pFirstMapped, VTMap);
  3558.         HandleExposures(pParent);
  3559.         }
  3560. #ifdef DO_SAVE_UNDERS
  3561.     if (dosave)
  3562.         DoChangeSaveUnder(pParent, pFirstSaveUndered->nextSib);
  3563. #endif /* DO_SAVE_UNDERS */
  3564.         WindowsRestructured ();
  3565.     }
  3566. }
  3567.  
  3568. static void
  3569. UnrealizeTree(pWin, fromConfigure)
  3570.     WindowPtr pWin;
  3571.     Bool fromConfigure;
  3572. {
  3573.     register WindowPtr pChild;
  3574.     void (*RegionEmpty)();
  3575.     Bool (*Unrealize)();
  3576.  
  3577.     RegionEmpty = pWin->drawable.pScreen->RegionEmpty;
  3578.     Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
  3579.     pChild = pWin;
  3580.     while (1)
  3581.     {
  3582.     if (pChild->realized)
  3583.     {
  3584.         pChild->realized = FALSE;
  3585.         pChild->visibility = VisibilityNotViewable;
  3586.         (* Unrealize)(pChild);
  3587.         DeleteWindowFromAnyEvents(pChild, FALSE);
  3588.         if (pChild->viewable)
  3589.         {
  3590. #ifdef DO_SAVE_UNDERS
  3591.         if (pChild->saveUnder)
  3592.             deltaSaveUndersViewable--;
  3593. #endif
  3594.         pChild->viewable = FALSE;
  3595.         if (pChild->backStorage)
  3596.             (*pChild->drawable.pScreen->SaveDoomedAreas)(
  3597.                         pChild, &pChild->clipList, 0, 0);
  3598.         if ((pChild != pWin) || fromConfigure)
  3599.         {
  3600.             (* RegionEmpty)(&pChild->clipList);
  3601.             (* RegionEmpty)(&pChild->borderClip);
  3602.         }
  3603.         pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  3604.         }
  3605.         if (pChild->firstChild)
  3606.         {
  3607.         pChild = pChild->firstChild;
  3608.         continue;
  3609.         }
  3610.     }
  3611.     while (!pChild->nextSib && (pChild != pWin))
  3612.         pChild = pChild->parent;
  3613.     if (pChild == pWin)
  3614.         return;
  3615.     pChild = pChild->nextSib;
  3616.     }
  3617. }
  3618.  
  3619. /*****
  3620.  * UnmapWindow
  3621.  *    If the window is already unmapped, this request has no effect.
  3622.  *    Otherwise, the window is unmapped and an UnMapNotify event is
  3623.  *    generated.  Cannot unmap a root window.
  3624.  *****/
  3625.  
  3626. UnmapWindow(pWin, fromConfigure)
  3627.     register WindowPtr pWin;
  3628.     Bool fromConfigure;
  3629. {
  3630.     register WindowPtr pParent;
  3631.     xEvent event;
  3632.     Bool wasRealized = (Bool)pWin->realized;
  3633.     Bool wasViewable = (Bool)pWin->viewable;
  3634.  
  3635.     if ((!pWin->mapped) || (!(pParent = pWin->parent)))
  3636.         return(Success);
  3637.     if (SubStrSend(pWin, pParent))
  3638.     {
  3639.     event.u.u.type = UnmapNotify;
  3640.     event.u.unmapNotify.window = pWin->drawable.id;
  3641.     event.u.unmapNotify.fromConfigure = fromConfigure;
  3642.     DeliverEvents(pWin, &event, 1, NullWindow);
  3643.     }
  3644.     if (wasViewable && !fromConfigure)
  3645.     {
  3646.     pWin->valdata = UnmapValData;
  3647.     MarkOverlappedWindows(pWin, pWin->nextSib);
  3648.     MarkWindow(pWin->parent);
  3649.     }
  3650.     pWin->mapped = FALSE;
  3651.     if (wasRealized)
  3652.     UnrealizeTree(pWin, fromConfigure);
  3653.     if (wasViewable)
  3654.     {
  3655.     if (!fromConfigure)
  3656.     {
  3657.         (* pWin->drawable.pScreen->ValidateTree)(pParent, pWin, VTUnmap);
  3658.         HandleExposures(pParent);
  3659.     }
  3660. #ifdef DO_SAVE_UNDERS
  3661.     if (DO_SAVE_UNDERS(pWin))
  3662.     {
  3663.         if (pWin->saveUnder ? ChangeSaveUnder(pWin, pWin->nextSib) :
  3664.                   CheckSaveUnder(pWin))
  3665.         {
  3666.         DoChangeSaveUnder(pParent, pWin->nextSib);
  3667.         }
  3668.     }
  3669.     pWin->DIXsaveUnder = FALSE;
  3670. #endif /* DO_SAVE_UNDERS */
  3671.     }
  3672.     if (wasRealized && !fromConfigure)
  3673.     WindowsRestructured ();
  3674.     return(Success);
  3675. }
  3676.  
  3677. /*****
  3678.  * UnmapSubwindows
  3679.  *    Performs an UnmapWindow request with the specified mode on all mapped
  3680.  *    children of the window, in bottom to top stacking order.
  3681.  *****/
  3682.  
  3683. UnmapSubwindows(pWin)
  3684.     register WindowPtr pWin;
  3685. {
  3686.     register WindowPtr pChild, pHead;
  3687.     xEvent event;
  3688.     Bool wasRealized = (Bool)pWin->realized;
  3689.     Bool wasViewable = (Bool)pWin->viewable;
  3690.     Bool anyMarked = FALSE;
  3691.     Mask parentNotify;
  3692.  
  3693.     if (!pWin->firstChild)
  3694.     return;
  3695.     parentNotify = SubSend(pWin);
  3696.     pHead = RealChildHead(pWin);
  3697.     for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
  3698.     {
  3699.     if (pChild->mapped)
  3700.         {
  3701.         if (parentNotify || StrSend(pChild))
  3702.         {
  3703.         event.u.u.type = UnmapNotify;
  3704.         event.u.unmapNotify.window = pChild->drawable.id;
  3705.         event.u.unmapNotify.fromConfigure = xFalse;
  3706.         DeliverEvents(pChild, &event, 1, NullWindow);
  3707.         }
  3708.         if (pChild->viewable)
  3709.         {
  3710.         pChild->valdata = UnmapValData;
  3711.         anyMarked = TRUE;
  3712.         }
  3713.         pChild->mapped = FALSE;
  3714.             if (pChild->realized)
  3715.         UnrealizeTree(pChild, FALSE);
  3716.         if (wasViewable)
  3717.         {
  3718. #ifdef DO_SAVE_UNDERS
  3719.         pChild->DIXsaveUnder = FALSE;
  3720. #endif /* DO_SAVE_UNDERS */
  3721.         if (pChild->backStorage)
  3722.             (*pChild->drawable.pScreen->SaveDoomedAreas)(
  3723.                         pChild, &pChild->clipList, 0, 0);
  3724.         }
  3725.     }
  3726.     }
  3727.     if (wasViewable)
  3728.     {
  3729.     if (anyMarked)
  3730.     {
  3731.         MarkWindow(pWin);
  3732.         (* pWin->drawable.pScreen->ValidateTree)(pWin, pHead, VTUnmap);
  3733.         HandleExposures(pWin);
  3734.     }
  3735. #ifdef DO_SAVE_UNDERS
  3736.     if (DO_SAVE_UNDERS(pWin))
  3737.     {
  3738.         if (CheckSaveUnder(pWin->firstChild))
  3739.         DoChangeSaveUnder(pWin, pWin->firstChild);
  3740.     }
  3741. #endif /* DO_SAVE_UNDERS */
  3742.     }
  3743.     if (wasRealized)
  3744.     WindowsRestructured ();
  3745. }
  3746.  
  3747.  
  3748. void
  3749. HandleSaveSet(client)
  3750.     register ClientPtr client;
  3751. {
  3752.     register WindowPtr pParent, pWin;
  3753.     register int j;
  3754.  
  3755.     for (j=0; j<client->numSaved; j++)
  3756.     {
  3757.         pWin = (WindowPtr)client->saveSet[j];
  3758.         pParent = pWin->parent;
  3759.         while (pParent && (wClient (pParent) == client))
  3760.             pParent = pParent->parent;
  3761.         if (pParent)
  3762.     {
  3763.             ReparentWindow(pWin, pParent, pWin->drawable.x - wBorderWidth (pWin),
  3764.                pWin->drawable.y - wBorderWidth (pWin), client);
  3765.         if(!pWin->realized && pWin->mapped)
  3766.         pWin->mapped = FALSE;
  3767.             MapWindow(pWin, client);
  3768.     }
  3769.     }
  3770.     xfree(client->saveSet);
  3771.     client->numSaved = 0;
  3772.     client->saveSet = (pointer *)NULL;
  3773. }
  3774.  
  3775. Bool
  3776. VisibleBoundingBoxFromPoint(pWin, x, y, box)
  3777.     register WindowPtr pWin;
  3778.     int x, y;   /* in root */
  3779.     BoxPtr box;   /* "return" value */
  3780. {
  3781.     if (!pWin->realized)
  3782.     return (FALSE);
  3783.     if ((* pWin->drawable.pScreen->PointInRegion)(&pWin->clipList, x, y, box))
  3784.         return(TRUE);
  3785.     return(FALSE);
  3786. }
  3787.  
  3788. Bool
  3789. PointInWindowIsVisible(pWin, x, y)
  3790.     register WindowPtr pWin;
  3791.     int x, y;    /* in root */
  3792. {
  3793.     BoxRec box;
  3794.  
  3795.     if (!pWin->realized)
  3796.     return (FALSE);
  3797.     if ((* pWin->drawable.pScreen->PointInRegion)(&pWin->borderClip,
  3798.                           x, y, &box))
  3799.         return(TRUE);
  3800.     return(FALSE);
  3801. }
  3802.  
  3803.  
  3804. RegionPtr
  3805. NotClippedByChildren(pWin)
  3806.     register WindowPtr pWin;
  3807. {
  3808.     register ScreenPtr pScreen;
  3809.     RegionPtr pReg;
  3810.  
  3811.     pScreen = pWin->drawable.pScreen;
  3812.     pReg = (* pScreen->RegionCreate)(NullBox, 1);
  3813.     (* pScreen->Intersect) (pReg, &pWin->borderClip, &pWin->winSize);
  3814.     return(pReg);
  3815. }
  3816.  
  3817.  
  3818. void
  3819. SendVisibilityNotify(pWin)
  3820.     WindowPtr pWin;
  3821. {
  3822.     xEvent event;
  3823.     event.u.u.type = VisibilityNotify;
  3824.     event.u.visibility.window = pWin->drawable.id;
  3825.     event.u.visibility.state = pWin->visibility;
  3826.     DeliverEvents(pWin, &event, 1, NullWindow);
  3827. }
  3828.  
  3829.  
  3830. #define RANDOM_WIDTH 32
  3831.  
  3832. #ifndef NOLOGOHACK
  3833. extern int logoScreenSaver;
  3834. static DrawLogo();
  3835. #endif
  3836.  
  3837. void
  3838. SaveScreens(on, mode)
  3839.     int on;
  3840.     int mode;
  3841. {
  3842.     int i;
  3843.     int what;
  3844.  
  3845.     if (on == SCREEN_SAVER_FORCER)
  3846.     {
  3847.         if (mode == ScreenSaverReset)
  3848.             what = SCREEN_SAVER_OFF;
  3849.         else
  3850.            what = SCREEN_SAVER_ON;
  3851.     if (what == screenIsSaved)
  3852.             return ;
  3853.     }
  3854.     else
  3855.         what = on;
  3856.     for (i = 0; i < screenInfo.numScreens; i++)
  3857.     {
  3858.         if (on == SCREEN_SAVER_FORCER)
  3859.         {
  3860.            (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
  3861.         }
  3862.         if (what == SCREEN_SAVER_OFF)
  3863.         {
  3864.         if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
  3865.         {
  3866.            (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
  3867.                               on);
  3868.         }
  3869.             else if (HasSaverWindow (savedScreenInfo[i].blanked))
  3870.         {
  3871.                 FreeResource(savedScreenInfo[i].wid, RT_NONE);
  3872.                 savedScreenInfo[i].pWindow = NullWindow;
  3873.         }
  3874.         continue;
  3875.         }
  3876.         else if (what == SCREEN_SAVER_ON)
  3877.         {
  3878.             if (screenIsSaved == SCREEN_SAVER_ON)  /* rotate pattern */
  3879.             {
  3880.         if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
  3881.             {
  3882.             WindowPtr pWin = savedScreenInfo[i].pWindow;
  3883. #ifndef NOLOGOHACK
  3884.             if (logoScreenSaver)
  3885.             (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
  3886. #endif
  3887.                 MoveWindow(pWin,
  3888.                    (short)(-(random() % RANDOM_WIDTH)),
  3889.                    (short)(-(random() % RANDOM_WIDTH)),
  3890.                        pWin->nextSib, VTMove);
  3891. #ifndef NOLOGOHACK
  3892.             if (logoScreenSaver)
  3893.             DrawLogo(pWin);
  3894. #endif
  3895.         }
  3896.         continue;
  3897.         }
  3898.             if (ScreenSaverBlanking != DontPreferBlanking)
  3899.         {
  3900.                 if ((* screenInfo.screens[i]->SaveScreen)
  3901.                          (screenInfo.screens[i], what))
  3902.                 {
  3903.                          savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
  3904.                          continue;
  3905.                 }
  3906.                 if ((ScreenSaverAllowExposures != DontAllowExposures) &&
  3907.             TileScreenSaver(i, SCREEN_IS_BLACK))
  3908.         {
  3909.             savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
  3910.             continue;
  3911.                 }
  3912.         }
  3913.         if ((ScreenSaverAllowExposures != DontAllowExposures) &&
  3914.         TileScreenSaver(i, SCREEN_IS_TILED))
  3915.             {
  3916.             savedScreenInfo[i].blanked = SCREEN_IS_TILED;
  3917.         }
  3918.             else
  3919.             savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
  3920.     }
  3921.     }
  3922.     screenIsSaved = what;
  3923. }
  3924.  
  3925. static Bool
  3926. TileScreenSaver(i, kind)
  3927.     int i;
  3928.     int    kind;
  3929. {
  3930.     int j;
  3931.     int result;
  3932.     XID attributes[3];
  3933.     Mask mask;
  3934.     WindowPtr pWin;        
  3935.     CursorMetricRec cm;
  3936.     unsigned char *srcbits, *mskbits;
  3937.     CursorPtr cursor;
  3938.     XID        cursorID;
  3939.     int    attri;
  3940.  
  3941.     mask = 0;
  3942.     attri = 0;
  3943.     switch (kind) {
  3944.     case SCREEN_IS_TILED:
  3945.         switch (WindowTable[i]->backgroundState) {
  3946.         case BackgroundPixel:
  3947.         attributes[attri++] = WindowTable[i]->background.pixel;
  3948.         mask |= CWBackPixel;
  3949.         break;
  3950.         case BackgroundPixmap:
  3951.         attributes[attri++] = None;
  3952.         mask |= CWBackPixmap;
  3953.         break;
  3954.         default:
  3955.         break;
  3956.         }
  3957.     break;
  3958.     case SCREEN_IS_BLACK:
  3959.     attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
  3960.     mask |= CWBackPixel;
  3961.     break;
  3962.     }
  3963.     mask |= CWOverrideRedirect;
  3964.     attributes[attri++] = xTrue;
  3965.  
  3966.     /*
  3967.      * create a blank cursor
  3968.      */
  3969.  
  3970.     cm.width=16;
  3971.     cm.height=16;
  3972.     cm.xhot=8;
  3973.     cm.yhot=8;
  3974.     srcbits = (unsigned char *)xalloc( PixmapBytePad(32, 1)*16);
  3975.     mskbits = (unsigned char *)xalloc( PixmapBytePad(32, 1)*16);
  3976.     if (!srcbits || !mskbits)
  3977.     {
  3978.     xfree(srcbits);
  3979.     xfree(mskbits);
  3980.     }
  3981.     else
  3982.     {
  3983.     for (j=0; j<PixmapBytePad(32, 1)*16; j++)
  3984.         srcbits[j] = mskbits[j] = 0x0;
  3985.     cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
  3986.     if (cursor)
  3987.     {
  3988.         cursorID = FakeClientID(0);
  3989.         if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
  3990.         {
  3991.             attributes[attri] = cursorID;
  3992.             mask |= CWCursor;
  3993.         cursor->refcnt++;
  3994.         }
  3995.     }
  3996.     }
  3997.  
  3998.     pWin = savedScreenInfo[i].pWindow =
  3999.      CreateWindow(savedScreenInfo[i].wid,
  4000.           WindowTable[i],
  4001.           -RANDOM_WIDTH, -RANDOM_WIDTH,
  4002.           (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
  4003.           (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
  4004.           0, InputOutput, mask, attributes, 0, serverClient,
  4005.           wVisual (WindowTable[i]), &result);
  4006.  
  4007.     if (!pWin)
  4008.     return FALSE;
  4009.  
  4010.     if (!AddResource(pWin->drawable.id, RT_WINDOW,
  4011.              (pointer)savedScreenInfo[i].pWindow))
  4012.     return FALSE;
  4013.  
  4014.     if (mask & CWBackPixmap)
  4015.     {
  4016.     pWin->backgroundState = BackgroundPixmap;
  4017.     pWin->background.pixmap = pWin->parent->background.pixmap;
  4018.     pWin->background.pixmap->refcnt++;
  4019.     (*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
  4020.     }
  4021.  
  4022.     MapWindow(pWin, serverClient);
  4023. #ifndef NOLOGOHACK
  4024.     if (kind == SCREEN_IS_TILED && logoScreenSaver)
  4025.     DrawLogo(pWin);
  4026. #endif
  4027.     return TRUE;
  4028. }
  4029.  
  4030. /*
  4031.  * FindWindowWithOptional
  4032.  *
  4033.  * search ancestors of the given window for an entry containing
  4034.  * a WindowOpt structure.  Assumptions:  some parent will
  4035.  * contain the structure.
  4036.  */
  4037.  
  4038. WindowPtr
  4039. FindWindowWithOptional (w)
  4040.     register WindowPtr w;
  4041. {
  4042.     do
  4043.     w = w->parent;
  4044.     while (!w->optional);
  4045.     return w;
  4046. }
  4047.  
  4048. /*
  4049.  * CheckWindowOptionalNeed
  4050.  *
  4051.  * check each optional entry in the given window to see if
  4052.  * the value is satisfied by the default rules.  If so,
  4053.  * release the optional record
  4054.  */
  4055.  
  4056. CheckWindowOptionalNeed (w)
  4057.     register WindowPtr w;
  4058. {
  4059.     register WindowOptPtr optional;
  4060.     register WindowOptPtr parentOptional;
  4061.  
  4062.     if (!w->parent)
  4063.     return;
  4064.     optional = w->optional;
  4065.     if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
  4066.     return;
  4067.     if (optional->otherEventMasks != 0)
  4068.     return;
  4069.     if (optional->otherClients != NULL)
  4070.     return;
  4071.     if (optional->passiveGrabs != NULL)
  4072.     return;
  4073.     if (optional->userProps != NULL)
  4074.     return;
  4075.     if (optional->backingBitPlanes != ~0L)
  4076.     return;
  4077.     if (optional->backingPixel != 0)
  4078.     return;
  4079. #ifdef SHAPE
  4080.     if (optional->boundingShape != NULL)
  4081.     return;
  4082.     if (optional->clipShape != NULL)
  4083.     return;
  4084. #endif
  4085. #ifdef XINPUT
  4086.     if (optional->inputMasks != NULL)
  4087.     return;
  4088. #endif
  4089.     parentOptional = FindWindowWithOptional(w)->optional;
  4090.     if (optional->visual != parentOptional->visual)
  4091.     return;
  4092.     if (optional->cursor != None && optional->cursor != parentOptional->cursor)
  4093.     return;
  4094.     if (optional->colormap != parentOptional->colormap)
  4095.     return;
  4096.     DisposeWindowOptional (w);
  4097. }
  4098.  
  4099. /*
  4100.  * MakeWindowOptional
  4101.  *
  4102.  * create an optional record and initialize it with the default
  4103.  * values.
  4104.  */
  4105.  
  4106. Bool
  4107. MakeWindowOptional (pWin)
  4108.     register WindowPtr pWin;
  4109. {
  4110.     register WindowOptPtr optional;
  4111.     register WindowOptPtr parentOptional;
  4112.  
  4113.     if (pWin->optional)
  4114.     return TRUE;
  4115.     optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
  4116.     if (!optional)
  4117.     return FALSE;
  4118.     optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
  4119.     optional->otherEventMasks = 0;
  4120.     optional->otherClients = NULL;
  4121.     optional->passiveGrabs = NULL;
  4122.     optional->userProps = NULL;
  4123.     optional->backingBitPlanes = ~0L;
  4124.     optional->backingPixel = 0;
  4125. #ifdef SHAPE
  4126.     optional->boundingShape = NULL;
  4127.     optional->clipShape = NULL;
  4128. #endif
  4129. #ifdef XINPUT
  4130.     optional->inputMasks = NULL;
  4131. #endif
  4132.     parentOptional = FindWindowWithOptional(pWin)->optional;
  4133.     optional->visual = parentOptional->visual;
  4134.     if (!pWin->cursorIsNone)
  4135.     {
  4136.     optional->cursor = parentOptional->cursor;
  4137.     optional->cursor->refcnt++;
  4138.     }
  4139.     else
  4140.     {
  4141.     optional->cursor = None;
  4142.     }
  4143.     optional->colormap = parentOptional->colormap;
  4144.     pWin->optional = optional;
  4145.     return TRUE;
  4146. }
  4147.  
  4148. DisposeWindowOptional (pWin)
  4149.     register WindowPtr pWin;
  4150. {
  4151.     if (!pWin->optional)
  4152.     return;
  4153.     /*
  4154.      * everything is peachy.  Delete the optional record
  4155.      * and clean up
  4156.      */
  4157.     if (pWin->optional->cursor)
  4158.     {
  4159.     FreeCursor (pWin->optional->cursor, (Cursor)0);
  4160.     pWin->cursorIsNone = FALSE;
  4161.     }
  4162.     else
  4163.     pWin->cursorIsNone = TRUE;
  4164.     xfree (pWin->optional);
  4165.     pWin->optional = NULL;
  4166. }
  4167.  
  4168. #ifndef NOLOGOHACK
  4169. static
  4170. DrawLogo(pWin)
  4171.     WindowPtr pWin;
  4172. {
  4173.     DrawablePtr pDraw;
  4174.     ScreenPtr pScreen;
  4175.     int x, y;
  4176.     unsigned int width, height, size;
  4177.     GC *pGC;
  4178.     int d11, d21, d31;
  4179.     xPoint poly[4];
  4180.     XID fore[2], back[2];
  4181.     xrgb rgb[2];
  4182.     BITS32 fmask, bmask;
  4183.     ColormapPtr cmap;
  4184.  
  4185.     pDraw = (DrawablePtr)pWin;
  4186.     pScreen = pDraw->pScreen;
  4187.     x = -pWin->origin.x;
  4188.     y = -pWin->origin.y;
  4189.     width = pScreen->width;
  4190.     height = pScreen->height;
  4191.     pGC = GetScratchGC(pScreen->rootDepth, pScreen);
  4192.     if (!pGC)
  4193.     return;
  4194.  
  4195.     if ((random() % 100) <= 17) /* make the probability for white fairly low */
  4196.     fore[0] = pScreen->whitePixel;
  4197.     else
  4198.     fore[0] = pScreen->blackPixel;
  4199.     if ((pWin->backgroundState == BackgroundPixel) &&
  4200.     (cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
  4201.     fore[1] = pWin->background.pixel;
  4202.     QueryColors(cmap, 2, fore, rgb);
  4203.     if ((rgb[0].red == rgb[1].red) &&
  4204.         (rgb[0].green == rgb[1].green) &&
  4205.         (rgb[0].blue == rgb[1].blue)) {
  4206.         if (fore[0] == pScreen->blackPixel)
  4207.         fore[0] = pScreen->whitePixel;
  4208.         else
  4209.         fore[0] = pScreen->blackPixel;
  4210.     }
  4211.     }
  4212.     fore[1] = FillSolid;
  4213.     fmask = GCForeground|GCFillStyle;
  4214.     if (pWin->backgroundState == BackgroundPixel) {
  4215.     back[0] = pWin->background.pixel;
  4216.     back[1] = FillSolid;
  4217.     bmask = GCForeground|GCFillStyle;
  4218.     } else {
  4219.     back[0] = 0;
  4220.     back[1] = 0;
  4221.     (void)DoChangeGC(pGC, GCTileStipXOrigin|GCTileStipYOrigin, back, 0);
  4222.     back[0] = FillTiled;
  4223.     back[1] = (XID)pWin->background.pixmap;
  4224.     bmask = GCFillStyle|GCTile;
  4225.     }
  4226.  
  4227.     size = width;
  4228.     if (height < width)
  4229.      size = height;
  4230.     size = RANDOM_WIDTH + random() % (size - RANDOM_WIDTH);
  4231.     size &= ~1;
  4232.     x += random() % (width - size);
  4233.     y += random() % (height - size);
  4234.  
  4235. /*
  4236.  *           -----
  4237.  *          /    /
  4238.  *         /    /
  4239.  *        /    /
  4240.  *       /    /
  4241.  *      /____/
  4242.  */
  4243.  
  4244.     d11 = (size / 11);
  4245.     if (d11 < 1) d11 = 1;
  4246.     d21 = (d11+3) / 4;
  4247.     d31 = d11 + d11 + d21;
  4248.     poly[0].x = x + size;              poly[0].y = y;
  4249.     poly[1].x = x + size-d31;          poly[1].y = y;
  4250.     poly[2].x = x + 0;                 poly[2].y = y + size;
  4251.     poly[3].x = x + d31;               poly[3].y = y + size;
  4252.     (void)DoChangeGC(pGC, fmask, fore, 1);
  4253.     ValidateGC(pDraw, pGC);
  4254.     (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  4255.  
  4256. /*
  4257.  *           ------
  4258.  *          /     /
  4259.  *         /  __ /
  4260.  *        /  /  /
  4261.  *       /  /  /
  4262.  *      /__/__/
  4263.  */
  4264.  
  4265.     poly[0].x = x + d31/2;                       poly[0].y = y + size;
  4266.     poly[1].x = x + size / 2;                    poly[1].y = y + size/2;
  4267.     poly[2].x = x + (size/2)+(d31-(d31/2));      poly[2].y = y + size/2;
  4268.     poly[3].x = x + d31;                         poly[3].y = y + size;
  4269.     (void)DoChangeGC(pGC, bmask, back, 1);
  4270.     ValidateGC(pDraw, pGC);
  4271.     (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  4272.  
  4273. /*
  4274.  *           ------
  4275.  *          /  /  /
  4276.  *         /--/  /
  4277.  *        /     /
  4278.  *       /     /
  4279.  *      /_____/
  4280.  */
  4281.  
  4282.     poly[0].x = x + size - d31/2;                poly[0].y = y;
  4283.     poly[1].x = x + size / 2;                    poly[1].y = y + size/2;
  4284.     poly[2].x = x + (size/2)-(d31-(d31/2));      poly[2].y = y + size/2;
  4285.     poly[3].x = x + size - d31;                  poly[3].y = y;
  4286.     ValidateGC(pDraw, pGC);
  4287.     (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  4288.  
  4289. /*
  4290.  * -----
  4291.  * \    \
  4292.  *  \    \
  4293.  *   \    \
  4294.  *    \    \
  4295.  *     \____\
  4296.  */
  4297.  
  4298.     poly[0].x = x;                     poly[0].y = y;
  4299.     poly[1].x = x + size/4;            poly[1].y = y;
  4300.     poly[2].x = x + size;              poly[2].y = y + size;
  4301.     poly[3].x = x + size - size/4;     poly[3].y = y + size;
  4302.     (void)DoChangeGC(pGC, fmask, fore, 1);
  4303.     ValidateGC(pDraw, pGC);
  4304.     (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  4305.  
  4306. /*
  4307.  *          /
  4308.  *         /
  4309.  *        /
  4310.  *       /
  4311.  *      /
  4312.  */
  4313.  
  4314.     poly[0].x = x + size- d11;        poly[0].y = y;
  4315.     poly[1].x = x + size-( d11+d21);  poly[1].y = y;
  4316.     poly[2].x = x + d11;              poly[2].y = y + size;
  4317.     poly[3].x = x + d11 + d21;        poly[3].y = y + size;
  4318.     (void)DoChangeGC(pGC, bmask, back, 1);
  4319.     ValidateGC(pDraw, pGC);
  4320.     (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
  4321.  
  4322.     FreeScratchGC(pGC);
  4323. }
  4324.  
  4325. #endif
  4326.